在c语言中,我们对文件用fopen,fread,fwrite,fclose等等c语言标准库函数来进行操作,实际上这些库函数是对系统调用接口的一个封装,目的是操作简单,方便编程。
以下介绍的是纯粹的系统调用接口来实现一些基础操作。
1.open() 函数
函数原型:
int open (const char* pathname,int flag);
int open (const char* pathname,int flag,mode_t mode);
pathname: 要打开的文件路径名flag: 文件的打开方式
必选项:
O_RDONLY---->只读打开
O_WRONLY---->只写打开
O_RDWR---->读写打开可选项:
O_CREAT:文件不存在,则创建
O_TRUNC:截断文件—丢弃原有数据
O_APPEND:追加写入
例子:w+ 在c语言中表示为 可读可写,文件不存在是创建文件,文件存在时截断内容为0
等价于O_RDWR|O_CREAT|O_TRUNC
mode: 打开文件的权限
当0_CREATE存在时,就一定要设置第三个参数 mode例子:open("./text.txt",O_RDWR|O_CREAT|O_TRUNC,0664)
在参数mode中,0664中的0不能被省略,涉及到特殊权限位返回值:成功则返回一个文件描述符(非负整数)作为文件操作句柄,失败返回-1
2.write()函数
函数原型: write(int fd,void char *buf,size_t len);
fd: open打开文件时候,返回的操作句柄----文件描述符
buf: 要写入文件数据空间的首地址(将buf指向的内容写入文件中)
len: 写入文件的字节数
返回值:成功返回写入文件的字节数,失败返回-1
3.read()函数
函数原型:ssize_t read(int fd,char *buf,size_t len);
fd: open打开文件时候,返回的操作句柄----文件描述符
buf: 一块空间的首地址,用于存放从文件中读取的数据
len: 读取的字节数 (len不能大于buf空间的大小)4.
4.lseek()函数
函数原型:off_t lseek(int fd,off_t offset,int whence);
fd: open打开文件时候,返回的操作句柄----文件描述符
offset: 偏移量
whence: 将文件流指针偏移到什么位置
SEEK_SET: 相对于文件开始位置偏移
SEEK_CUR: 相对于文件当前位置偏移
SEEK_END: 相对于文件结尾位置偏移
返回值:跳转后,读写位置相对于文件起始位置的偏移量
失败返回-1
5.close()函数
函数原型:int close(int fd);
简单代码实现:
运行结果:
通过上面的一些系统调用接口,我们知道文件描述符是一个非负整数,我们知道在Linux下,一切皆可以看成文件,Linux中规定每一个文件对应一个索引(相当于数组的下标)在对这些文件进行操作的时候,就通过索引就可以直接找到文件进行操作,而文件描述符就是内核为了高效管理这些已经打开的文件而创建的索引。
我们知道在Linux下,0代表标准输入,1代表标准输出,2代表标准错误。在程序刚刚启动的时候,会默认打开3个文件描述符,分别是标准输入0,标准输出1,标准错误2,也就是说在此之后,新创建的文件,它的文件描述符为3,继续创建文件,文件描述符为4,以此类推。
当打开一个文件时,内核会在文件描述符表中寻找一个空闲且最小的文件描述符(下标最小的位置)
Linux内核对这些已经打开的文件创建一个文件描述表来进行管理,如下图:
注意:同一个文件可以被多次打开,但是每打开一次都需要一个新的文件描述符,这就说明同一个进程的不同文描述符可以指向同一个文件。
1.基本概念
把原本要写入A文件的数据,在不改变程序逻辑的情况下,写入到B文件
具体符号表示:
> 清空重定向
ls >test.txt 将ls的结果输出到文件test.txt中
解释:ls 默认把浏览结果输出到屏幕(就是将数据写入标准输出),加重定向符号>后,数据的流向改变,数据将不在写入标准输出,而是写入文件test.txt中,所以文件test.txt中会写入ls的结果
>> 追加重定向
符号>>和>的区别:重定向符号>,是将原文件中的内容先清空,后将数据写入;而重定向符号>>是直接将数据写入
重定向原理:
通过改变文件描述符对应的文件描述信息(struct file结构体),来改变所操作的文件,实现数据流向的改变。
接口:int dup2(int oldfd,newfd);
功能:让newfd对应的位置保存oldfd对应位置的信息,相当于把newfd重定向到oldfd
(如果newfd本身已经打开了一个文件,则重定向前,会将对应的文件先关闭释放掉)
简单代码实现:
运行结果: