一. C语言的文件操作函数
(1)fopen 函数
函数原型: File * fopen ( const char* pathname , const char * mode)
功能:创建并打开一个文件;
参数:pathname 表示打开文件的路径,mode 表示打开文件的权限 ;
- "r" 以只读方式打开文件,该文件必须存在。
- "w" 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
- "w+" 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
- "a" 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
- "a+" 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。(原来的EOF符不保留)
- "wb" 只写打开或新建一个二进制文件,只允许写数据。
- "wb+" 读写打开或建立一个二进制文件,允许读和写。
- "ab" 追加打开一个二进制文件,并在文件末尾写数据。
- "ab+"读写打开一个二进制文件,允许读,或在文件末追加数据。
返回值:文件顺利打开后,指向该流的文件指针将被返回,文件打开失败 ,返回NULL指针,并保存错误信息。
(2)fwrite( )函数
函数原型:size_t fwrite( const void* buf, size_t size,size_t count, FILE* stream)
功能:将文件写入流中;
参数:buf 指向数据块的指针,size 表示每个数据的大小 ,count 不是数据的个数,stream 文件指针;
注意:返回值随着调用格式的不同而不同:
(1) 调用格式:fwrite(buf,sizeof(buf),1,fp);
成功写入返回值为1(即count)
(2)调用格式:fwrite(buf,1,sizeof(buf),fp);
成功写入则返回实际写入的数据个数(单位为Byte);
(3)fread ( ) 函数
函数原型:size_t fread ( const void* buf, size_t size,size_t count, FILE* stream)
参数:buf 指向数据块的指针,size 表示每个数据的大小 ,count 不是数据的个数,stream 文件指针;
注意:返回值随着调用格式的不同而不同:
(1) 调用格式:fread (buf,sizeof(buf),1,fp);
读取成功时:当读取的数据量正好是sizeof(buf)个Byte时,返回值为1(即count);
否则返回值为0(读取数据量小于sizeof(buf));
(2)调用格式:fread(buf,1,sizeof(buf),fp);
读取成功返回值为实际读回的数据个数(单位为Byte);
二. Linux 下文件系统调用函数
在Linux下文件系统函数主要有 open ,close ,write ,read 等。
1. open 函数
功能:以某种方式打开文件
参数:pathname 要打开和创建的目标文件 ,flag 打开文件时,可以传入多个参数选项,用一个或者多个常量进行“或”运算。
O_REONLY :只读方式打开文件
O_WRONLY :可写方式打开文件
O_RDWR :读写方式打开文件
O_CREAT :如果文件不存在时就创建一个新文件,并用第三个参数为其设置权限。
O_EXCL :如果使用O_CREAT 时文件存在,则可返回错误信息。这一参数可测试文件是否存在。
O_NOCTTY :使用本参数时,如文件为终端,那么终端不可以作为调用open ()系统调用的那个进程的控制终端。
O_TRUNC :如文件已经存在,并且以只读或只写成功打开,那么会先全部删除文件中原因数据。
O+APPEND :以添加方式打开文件,在打开文件的同时,文件指针指向文件末尾。
返回值:成功 返回新打开的文件描述符;失败 -1。
注:open函数具体使用哪个,需要根据应用场景来看。如果目标文件不存在,需要open创建,则第三个参数表示创建文件的默认权限,否则,使用两个参数的open函数。
2. write 函数
函数原型:ssize_t write ( int fd,void *buf,size_t count )
参数:fd 文件描述符,buf 数据缓冲区 ,count 写入的字节数
返回值:成功 写入的字节数,失败 -1;
3. read 函数
函数原型 :ssize_t write ( int fd,void *buf,size_t count )
参数:fd 文件描述符,buf 数据缓冲区 ,count 读入的字节数
返回值:成功 读入的字节数,失败 -1;
大家可以利用man 手册来学习其他的文件系统函数。
三 . 文件描述符
1. 文件描述符的定义
简单理解,文件描述符就是描述文件的符号。内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。
习惯上,Linux进程中有三个默认的文件描述符,标准输入(0),标准输出(1),标准错误(2);
2. 文件描述符的理解
我们知道,系统在创建一个进程时,会创建出描述进程的PCB,PCB里面存储着关于进程的一切相关信息,当一个进程要打开一个文件时,PCB里面会添加一个文件指针,这个文件指针指向管理文件的结构体FILE_struct,而结构体FILE_struct包含描述和组织文件的信息,其中有一项就是文件指针数组,这个文件指针数组的每个单元都指向一个对应的文件,而文件指针数组的下标就是文件描述符。实际上,系统就是根据用户所提供的文件描述符来找到文件指针数组对应的单元,从而找到对应的文件。
3.文件描述符的分配规则
在file_struct的数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
四. C语言的文件操作函数与系统文件操作函数的比较
1. 首先对比函数名,我们可以发现,C语言库的文件操作函数都是 f #组成的,属于调用库函数,而系统函数没有f,属于调用系统函数。可以认为 C库函数 f #系列的函数。都是对系统函数的封装,方便二次开发。
2. C标准库对 f #系列函数提供了用户级缓冲区,而系统函数没有提供缓冲区。