前言:本篇主要讲解底层文件系统接口,详细介绍 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)
文件的本质实际上是进程与打开文件之间的关系。
因此文件操作和进程有关系,我们写一下我们的代码,获取进程 ,查一下进程信息:
#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 拿到进程 后,得益于 "昏睡指令" while(1){sleep(1);)
我们的进程就一直的跑着,再打开一个窗口,通过 $ls proc 指令检视该进程信息:


最低0.47元/天 解锁文章
1278

被折叠的 条评论
为什么被折叠?



