Linux下对文件操作有两种方式:系统调用(system call)和库函数调用(Library functions)。系统调用实际上就是指最底层的一个调用,在linux程序设计里面就是底层调用的意思,面向的是硬件。而库函数调用则面向的是应用开发的,相当于应用程序的api,采用这样的方式有很多种原因,第一:双缓冲技术的实现。第二,可移植性。第三,底层调用本身的一些性能方面的缺陷。第四:让api也可以有了级别和专门的工作面向。
【库函数调用——缓冲文件系统】
缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用。
当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓冲区”依此读入接收的变量。执行写文件的操作时,先将数据写入内存“缓冲区”,待内存“缓冲区”装满后再写入文件。由此可以看出,内存 “缓冲区”的大小,影响着实际操作外存的次数,内存“缓冲区”越大,则操作外存的次数就少,执行速度就快、效率高。一般来说,文件“缓冲区”的大小随机器而定。
缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符、字符串、格式化数据,也可以读写二进制数据。
C库调用就是属于缓冲文件系统,例如:fopen, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, freopen, fseek, ftell, rewind等是带缓冲的。
【系统调用——非缓冲文件系统】
非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它使用文件描述符来表示文件,只能读写二进制文件,但效率高、速度快。Linux系统调用就属于非缓冲文件系统,例如:open, close, read, write, getc, getchar, putc, putchar 等是不带缓冲的。
文件描述符是一些小数值,你可以通过它们访问的打开的文件设备,而有多少文件描述符可用取决于系统的配置情况。但是当一个程序开始运行时,它一般会有3个已经打开的文件描述符,就是
0:标准输入
1:标准输出
2:标准错误
那些数学(即0、1、2)就是文件描述符,因为在Linux上一切都是文件,所以标准输入(stdin),标准输出(stdout)和标准错误(stderr)也可看作文件来对待。
一、系统调用——非缓冲文件系统
A、open系统调用
open函数的原型为:
int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode);
参数说明:
path,是包括路径的完整文件名,
oflags是文件访问模式(即是什么方式打开文件,只读、只写还是可读并可写等),
mode用于设定文件的访问权限。具体的可选参数,可以自己查看手册页,这里不一一详述。
返回值说明:
open建立了一条到文件或设备的访问路径,如果调用成功,返回一个可以被read、write等其他系统调用的函数使用的文件描述符,而且这个文件描述是唯一的,不与任何其他运行中的进程共享,在失败时返回-1,并设置全局变量errno来指明失明的原因。
B、write系统调用
write函数的原型为:
size_t write(int fildes, const void *buf, size_t nbytes);
函数说明:
write的作用是把缓冲区buf的前nbytes个字节写入到 文件描述符fildes关联的文件中,返回实际写入的字节数。返回0表示没有写入任何数据,返回-1表示调用中出现了错误,错误代码保存在errno中。size_t read(int fildes, void *buf, size_t nbytes);
函数说明:
read系统调用的作用是从与文件描述符相关的文件里读入nbytes个字节的数据,并把它们放到数据区buf中,返回读入的字节数,失败时返回-1。int close(int fildes);
函数说明:
close函数的作用是终于文件描述符fildes一其对应的文件之间的关联。二、库函数调用——缓冲文件系统
FILE* fopen(const char *filename, const char *mode);
size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
int fclose(FILE *stream);
实例:
#include
main()
{
FILE *fp;
char ch;
if((fp=fopen("d:\\jrzh\\example\\c1.txt","rt"))==NULL)
{
printf("\nCannot open file strike any key exit!");
getch();
exit(1);
}
ch=fgetc(fp);
while(ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
fclose(fp);
附:
C库文件操作标准库函数汇总:
文件的打开操作 fopen 打开一个文件
文件的关闭操作 fclose 关闭一个文件
文件的读写操作 fgetc 从文件中读取一个字符
fputc 写一个字符到文件中去
fgets 从文件中读取一个字符串
fputs 写一个字符串到文件中去
fprintf 往文件中写格式化数据
fscanf 格式化读取文件中数据
fread 以二进制形式读取文件中的数据
fwrite 以二进制形式写数据到文件中去
getw 以二进制形式读取一个整数
putw 以二进制形式存贮一个整数
文件状态检查函数 feof 文件结束
ferror 文件读/写出错
clearerr 清除文件错误标志
ftell 了解文件指针的当前位置
文件定位函数 rewind 反绕
fseek 随机定位
【区别】
1、本质:缓冲与非缓冲;
2、操作:系统调用通过文件描述符来操作文件,而库函数通过文件指针操作文件;
系统调用只能以二进制的形式读写文件,而库函数可以以二进制、字符、字符串、格式化数据读写文件;
3、效率:系统调用效率更高。