序言
空文件占不占据磁盘空间?占据
文件=内容+属性
1.所有对文件的操作:a.对内容的操作,b.对属性的操作
2.储存文件,储存内容+数据
3.访问文件
访问文件的对象是(即打开文件的操作)进程,进程访问文件
打开前:普通的磁盘文件
打开后:将文件加载到内存(供cpu访问) 加载磁盘上的文件,一定涉及到访问磁盘设备(外设)---------操作系统来做
4.一个进程可以打开多个文件,多个进程可以打开多个文件
1----->n
操作系统运行很多个文件会对这么多打开的文件进行管理(先描述,后组织)
形成一个结构体来管理
struct xxxx{
//文件属性
struct xxxx *next;
......
}
重点:对文件的管理就成了对一个链表的增删查改的操作
文件被打开,文件属性怎么知道?同样,属性也会被存在磁盘,文件被打开时文件属性也被访问
5.文件按照是否被打开,分为:被打开的文件,没有打开的文件
内存中 磁盘中
6.本次研究文件本质,重点:进程 与 被打开文件的关系
C语言文件操作原理
回顾C语言函数对文件的操作:
FILE* 叫做文件指针也叫文件句柄
#include<stdio.h>
{
FILE* fp = fopen("log.txt","w");//w方式打开文件,不存在创建,第一个参数不指定路径为相对路径
if(fp==NULL)
{
perror("fopen");
}
const char* tmp = "aaaaaaaaaa";
fputs(tmp,fp);
return 0;
}
重新写入前:
hello linux file
hello linux file
hello linux file
hello linux file -------- 写入后:aaaaaaaa
hello linux file -------fputs为什么会覆盖?
hello linux file
hello linux file
hello linux file
以写方式打开文件时,会先清空文件
直接清空方式
打开一次文件
> log.txt(输出重定向,以W方式打开)
echo “aaaa” >> log.txt(追加重定向)
打开方式
r:读
w:写
a:追加写入
认识系统文件接口
一个进程打开文件
进程通过操作系统打开文件,调用系统访问文件的接口
C语言打开文件底层一定封装了OS接口
那怎么证明呢?
open返回值:失败返回-1
成功返回>0的整数fd
open(要打开的文件,要打开文件的标志位)
关于函数传入标志位的技巧----linux中常用的传参方式:
整数,包含32个bit,标志位为0或1,所以可以使用不同的bit位来分别传参
对于这个函数标志位包含的功能
多说无益,设计一个用比特位–位图方式传参的接口:
#include<stdio.h>
#define Print1 1 //0001
#define Print2 (1<<1) //0010 1左移1位相当于Print2 2
#define Print3 (1<<2) //0100
#define Print4 (1<<3) //1000
void Print(int flags)
{
if(flags&Print1) printf("hello 1\n");
if(flags&Print2) printf("hello 2\n");
if(flags&Print3) printf("hello 3\n");
if(flags&Print4) printf("hello 4\n");
}
int main()
{
Print(Print1);
Print(Print1|Print2);
Print(Print1|Print2|Print3);
Print(Print4);
return 0;
}
结果:
看结果,位图运算输入1,就打印1
输入1|2,打印1,2
根据这一思想,实现open函数参数的意思就容易了:
可以看到:创建成功
但是权限很奇怪
生成时没有指明创建权限,所以临时文件是一个乱码式文件
所以open函数的第二个函数,第三个参数表示权限,类型为权限整数,之前的0666,0777等
再次查看结果:
文件正常,文件权限=0666-(~umask)
自定义方式去掉权限掩码man 2 umask查看这个函数的使用(这边是有关linux权限操作的内容,可看博主之前的文章)点击直达
umask(0);
int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
int fd = open("log.txt",O_WRONLY | O_CREAT | O_APPEND,0666);
if(fd < 0)
{
perror("open");
return 1;
}
注意的是,系统的权限掩码仍然为0002
根据就近原则,听从这边文件的权限掩码
操作文件:
向文件内写入:
文件的fd
返回值网络部分再说,写入操作实现:
可以看到多了^@,\0是C语言的规定,文件系统并不需要\0,这边也不用在文本文件+1
write(fd, msg, strlen(msg));
写入一段aaaaaaaaa\n
成功,
在修改代码输入bbb\n
说明write写入不会覆盖式写入
覆盖式写入实现:
int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
追加写入实现:
int fd = open("log.txt",O_WRONLY | O_CREAT | O_APPEND,0666);
执行几次写入几次
语言和系统与文件之间的关系
探究fd值是什么?
现象
fd是一个连续的小整数
像数组下标
理解文件在操作系统中的表现
什么关系?操作系统要访问文件只认文件描述符
FILE是什么 -----> 是一个 结构体,它里面必定封装了文件描述符
证明:
printf("fd->stdin:%d\n",stdin->_fileno);
printf("fd->stdout:%d\n",stdout->_fileno);
printf("fd->stderr:%d\n",stderr->_fileno);
FILE* fd = fopen("test.txt","w");
printf("fd->stdin:%d\n",fd->_fileno);
1.默认打开std三个标准输入输出报错流是为了程序员能方面写代码
2.stderr是什么?下篇见分晓
3.如何理解一切皆是文件!
有帮助请三连,有问题可以私信或者评论留言,都会看的~~