缓冲文件系统(fopen/fread/fwrite)和非缓冲文件系统(open/read/write)
Posted “好记性不如”烂博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓冲文件系统(fopen/fread/fwrite)和非缓冲文件系统(open/read/write)相关的知识,希望对你有一定的参考价值。
open:系统调用,返回的是文件描述符,即文件句柄,是文件在文件描述副表里的索引。
fopen:C语言库函数,返回的是一个指向文件结构的指针。fopen是ANSI C标准中的C语言库函数,在不同的操作系统中应该调用不同的内核API,UNIX环境下,fopen是对open的封装。
文件描述符是UNIX/Linux下的一个概念,Linux环境下,一切设备皆是文件,一切设备皆是以文件的形式进行操作,如网络套接字、硬件设备等。
设备文件不可以当成流式文件来处理,因此,只能使用open,而fopen只是用来操纵正规文件的,并且设置有缓冲,跟open还是有区别的。
open和fopen的区别在于:
1.缓冲文件系统
缓冲文件系统是借助于文件结构体指针FILE *来对文件进行管理,通过文件指针对文件进行访问,即可以读写字符、字符串、格式化数据,也可以读写二进制数据。
缓 冲文件系统特点:在内存中开辟一个“缓冲区”,为程序里每一个文件使用,当执行读文件操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓冲区”依次读入接收的变量。执行写文件操作时,也是先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存“缓冲区”的大 小,影响着实际操作外在的次数,内存“缓冲区”越大,则操作外存的次数就越少,执行速度就越快,效率就越高。一般来说,文件“缓冲区”的大小跟机器是相关的。
缓冲文件系统的IO函数主要包括:fopen, fclose, fread, fwrite, fgetc,fgets, fputc, fputs, freopen, fseek, ftell, rewind等。
2.非缓冲文件系统
非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件(对于UNIX系统内核而言,文本文件和二进制代码文件并无区别),但效率高、速度快,由于ANSI标准不再包括非缓冲文件系统,因此,在读取正规的文件时,建议大家最好不要选择它。
非缓冲文件系统的IO函数主要包括:open, close, read, write, getc,getchar, putc, putchar等。
两者的区别:
- fopen 系列是标准的C库函数;open系列是 POSIX 定义的,是UNIX系统里的systemcall。
也就是说,fopen系列更具有可移植性;而open系列只能用在 POSIX 的操作系统上。 - 使用fopen 系列函数时要定义一个指代文件的对象,被称为“文件句柄”(filehandler),是一个结构体;而open系列使用的是一个被称为“文件描述符” (file descriptor)的int型整数。
- fopen 系列是级别较高的I/O,读写时使用缓冲;而open系列相对低层,更接近操作系统,读写时没有缓冲。由于能更多地与操作系统打交道,open系列可以访问更改一些fopen系列无法访问的信息,如查看文件的读写权限。这些额外的功能通常因系统而异。
- 使用fopen系列函数需要"#include<sdtio.h>";使用open系列函数需要"#include <fcntl.h>" ,链接时要之用libc(-lc)
小结:
总的来说,为了使程序获得更好的可移植性,未到非得使用一些fopen系列无法实现的功能的情况下,fopen系列是首选。
函数原型:
FILE fopen(constchar filename,constchar* mode );
filename 是字符串,用来命名文件,mode 为访问模式的值
int fclose( FILE *fp );
如果成功关闭文件,fclose( ) 函数返回零,如果关闭文件时发生错误,函数返回 EOF。
size_t fread(void *ptr, size_tsize_of_elements, size_tnumber_of_elements, FILE *a_file);
size_t fwrite(constvoid *ptr, size_tsize_of_elements, size_tnumber_of_elements, FILE *a_file);
文件描述符和文件指针的区别
文件描述符就是open文件时产生的一个整数,一般用fd表示,其实就是一个索引,在UNIX系统中,用来标识文件。
文件指针是是一个指向FILE的结构体,在这个结构体当中,文件描述符是它的元素之一。它用于ANSI C标准的IO库调用中,用来标识文件。
因为FILE结构体中包含了文件描述符,所以我们在调用open() 打开一个文件的时候,会通过来这个open来获得文件描述符fd。
对于一个文件来说,它的文件描述符是唯一的,但是它的文件指针却不是唯一的,只是这些指针指向的对象是唯一的,也就是这个文件。
FILE *中除了包含了fd信息,还包含了IO缓冲,所以可以理解为FILE是对fd的封装,是C标准形式,所以FILE *比fd更适合跨平台,一般情况下优先选择fopen。
C语言文件指针与文件描述符之间可以相互转换:
int fileno(FILE *stream);
FILE *fdopen(int fd, const char *mode);
以上是关于缓冲文件系统(fopen/fread/fwrite)和非缓冲文件系统(open/read/write)的主要内容,如果未能解决你的问题,请参考以下文章