我们之前一直在学习进程,但是在最开始的时候,我们讲过linux下一切皆文件,但是什么才是真正的文件呢,我们使用mkdir,cd,都是在创造,使用文件,但是只停留在表面上,今天我们将学习一下什么才是真正的文件
1.狭义理解
⽂件在磁盘⾥
磁盘是永久性存储介质,因此⽂件在磁盘上的存储是永久性的
磁盘是外设(即是输出设备也是输⼊设备)
磁盘上的⽂件 本质是对⽂件的所有操作,都是对外设的输⼊和输出 简称 IO
所以以后只要是不做说明的文件,我们都默认为狭义文件
2.⼴义理解
Linux 下⼀切皆⽂件(键盘、显⽰器、⽹卡、磁盘...... 这些都是抽象化的过程)(后⾯会讲如何去
理解)
3.⽂件操作的归类认知
对于 0KB 的空⽂件是占⽤磁盘空间的(文件 = 属性 + 内容(空),但是属性不空)
⽂件是⽂件属性(元数据)和⽂件内容的集合(⽂件 = 属性(元数据)+ 内容)
所有的⽂件操作本质是⽂件内容操作和⽂件属性操作
4.系统⻆度
对⽂件的操作本质是进程对⽂件的操作
磁盘的管理者是操作系统
⽂件的读写本质不是通过 C 语⾔ / C++ 的库函数来操作的(这些库函数只是为⽤⼾提供⽅便),⽽真正对文件操作是通过⽂件相关的系统调⽤接⼝来实现的
5.回顾C⽂件接⼝
我们在c语言之中,最常用的就是fopen与fclose打开关闭文件
下面我们回顾一下这两个接口
写⽂件
hello.c:
cpp
#include <stdio.h>
#include <string.h>
int main()
{
FILE* fp = fopen("log.txt", "w");
if (fp == NULL)
{
perror("fopen");
return 1;
}
for (int i = 0; i < 10; i++)
{
char buffer[1024];
const char* message = "Hello Linux";
snprintf(buffer, sizeof(buffer), "%s : %d\n", message, i);
fwrite(buffer, strlen(buffer), 1, fp);
}
fclose(fp);
return 0;
}
下面是运行结果,创造了log.txt并且里面的内容是我们想看到的内容

读⽂件
读文件顾名思义就是把文件内容读取出来,我们要是读出来并且打印出来,不就是cat命令了吗
所以我们下面实现一个自己的cat命令
mycat:
cpp
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Usage : ./mycat filename\n");
return 1;
}
FILE* fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror("fopen");
return 1;
}
while (1)
{
char message[1024];
int n = fread(message, 1, sizeof(message) - 1, fp);
if (n > 0)
{
message[n] = '\0';
printf("%s", message);
}
if (feof(fp))
{
break;
}
}
fclose(fp);
return 0;
}
运行结果符合预期

6.再探写文件
我们修改一下hello.c代码
cpp
#include <stdio.h>
#include <string.h>
int main()
{
FILE* fp = fopen("log.txt", "w");
if (fp == NULL)
{
perror("fopen");
return 1;
}
//for (int i = 0; i < 10; i++)
//{
// char buffer[1024];
// const char* message = "Hello Linux";
// snprintf(buffer, sizeof(buffer), "%s : %d\n", message, i);
// fwrite(buffer, strlen(buffer), 1, fp);
//}
fclose(fp);
return 0;
}
发现直接将log.txt清除了!!

所以我们知道了,fopen(w)的时候,是先将文件清空,然后再写入内容,所以我们得使用"a"追加内容
我们再来看看echo message > filename这个命令

发现和fopen(w)的现象一样,都是先清除再写入,所以我们可以写出一个echo > ,即用fopen(w)打开,然后写入内容
那么echo message >> filename呢

发现是追加,即和fopen(a)的现象一样,都是追加写入,所以我们可以写出一个echo > >,即用fopen(a)打开,然后写入内容
7.stdin & stdout & stderr
C默认会打开三个输⼊输出流,分别是stdin, stdout, stderr
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,⽂件指针
cpp
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;
这也间接说明我们操作的都是文件,即一切皆文件