(19)Linux系统下的文件操作 && 文件系统接口

前言:本篇主要讲解底层文件系统接口,详细介绍 open 接口和它的 flags 参数 (即系统传递标记位),重点讲解 O_RDWR, O_RDONLY, O_WRONLY, O_CREAT 和 O_APPEND 这些操作模式。

一、先来段代码回顾C文件接口 

hello.c写文件 

#include <stdio.h>
#include <string.h>
int main()
{
 FILE *fp = fopen("myfile", "w");
 if(!fp){
 printf("fopen error!\n");
 }
 const char *msg = "hello bit!\n";
 int count = 5;
 while(count--){
 fwrite(msg, strlen(msg), 1, fp);
 }
 fclose(fp);
 return 0;
}

 hello.c读文件

#include <stdio.h>
#include <string.h>
int main()
{
 FILE *fp = fopen("myfile", "r");
 if(!fp){
 printf("fopen error!\n");
 }
 char buf[1024];
 const char *msg = "hello bit!\n";
 while(1){
 //注意返回值和参数,此处有坑,仔细查看man手册关于该函数的说明
 ssize_t s = fread(buf, 1, strlen(msg), fp);
 if(s > 0){
 buf[s] = 0;
 printf("%s", buf);
 }
 if(feof(fp)){
 break;
 }
 }
 fclose(fp);
 return 0;
}

 输出信息到显示器,你有哪些方法

#include <stdio.h>
#include <string.h>
int main()
{
 const char *msg = "hello fwrite\n";
 fwrite(msg, strlen(msg), 1, stdout);
 printf("hello printf\n");
 fprintf(stdout, "hello fprintf\n");
 return 0;
}

1、 关于文件操作的思考

我们曾经讲过:文件 = 文件内容 + 文件属性  

文件属性也是数据!这意味着,即便你创建一个空文件,也要占据磁盘空间!所以:

                                ② 文件操作 = 文件内容的操作 + 文件属性的操作 

 因此,在操作文件的过程中,既改变内容又改变属性的情况很正常,不要把它们割裂开来!

那么,所谓的 "打开" 文件,究竟在做什么? ③ 

"打开文件不是目的,访问文件才是目的!" 

访问文件时,都是要通过 fread,fwrite,fgets... 这样的代码来完成对文件的操作的,

如果通过这些方式,那么 "打开" 文件就需要 将文件的属性或内容加载到内存 (memory) 中!

因为这是由冯诺依曼体系结构决定的,将来 \textrm{CPU} 要执行 fread,fwrite 来对文件进行读写的。

 既然如此……  是不是所有的文件都会处于被打开的状态呢?并不是! 

那没有被打开的文件在哪里?

对于文件的理解,在宏观上我们可以区分成 内存文件 (打开的文件) 和 磁盘文件。  (存储在磁盘中) 

通常我们打开文件、访问文件和关闭文件,是谁在进行相关操作?

运行起来的时候,才会执行对应的代码,然后才是真正的对文件进行相关的操作。
实际上是  进程在对文件进行操作! 在系统角度理解是我们曾经写的代码变成了进程。

进程执行调度对应的代码到了 fopen,write 这样的接口,然后才完成了对文件的操作。
当我执行 fopen 时,对应地就把文件打开了,所以文件操作和进程之间是撇不开关系。

🔺 结论:学习文件操作,实际上就是学习 "进程" 与 "打开文件" 的关系。 ⑦
 

2、当前路径(Current Path)

文件的本质实际上是进程与打开文件之间的关系。

 因此文件操作和进程有关系,我们写一下我们的代码,获取进程 \textrm{pid},查一下进程信息:

#include <stdio.h>
#include <unistd.h>
 
int main(void)
{
    FILE* pf = fopen("log.txt", "w"); // 写入
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
 
    /* 获取进程 pid */
    printf("Mypid: %d\n", getpid());
 
    /* 打开文件后,等一等,方便查询 */
    while (1) {
        sleep(1);
    }
 
    const char* msg = "hello!";
    int count = 1;
    while (count <= 10) {
        fprintf(pf, "%s: %d\n", msg, count++);
    }
 
    fclose(pf);
}

getpid 拿到进程 \textrm{pid} 后,得益于 "昏睡指令" while(1){sleep(1);) 

我们的进程就一直的跑着,再打开一个窗口,通过 $ls proc 指令检视该进程信息:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值