C语言晋级--ANSI C文件管理
本篇文章的重点是理解ANSI C文件库,包括文件指针的概念;文件和流之间的关系;文本和二进制文件;文件的基本操作。ANSI 的 C 的标准库封装了文件的系统调用,为了提高文件打开的效率还加入了缓冲机制,提供记录的形式读写文件,并且有很好的移植性,是linux C语言最基础的文件编程。
一、文件指针和六流
typedef struct {
int level; //缓冲区填充的级别
unsigned flags; //文件状态标志
char fd; //文集爱你描述符
unsigned char hold;
int bsize; //缓冲区大小
unsigned char_FAR *buffer; //数据传输缓冲区
unsigned char_FAR *curp; //当前有效指针
unsigned istemp;
short token; //供有效检查使用
}FILE;
二、储存方式
两种储存方式分别为:文本方式、二进制方式
文件方式: 又称为ASCII文件,每一个字符都是一个ASCII码,文本文件的储存量大,便由于对字符进行操作,但是操作速度较慢;
二进制方式:将数据按照内存中的储存形式形式存储形式进行存放,二进制文件的容量小,存储速度快,适合存放中间结果;
在Linux中文件是按照二进制的形式储存的,用户打开的时候根据用户指定的打开方式进行存取;
三、输出、输入
Linux为每个进程都定了标准输入、标准输出和标准错误三个文件流,也称I/O数据流,系统与定义的三个文件流都有自己固定的名称,因此无需创建可以直接使用。
stdin:标准输入,默认是从键盘上读取数据
stdout:标准输出,默认向屏幕输出数据
stderr:标准错误,默认向屏幕输出数据
3个I/O数据流定义在stdio.h头文件里,程序在运行之前需要引用相关的头文件。C语言的标准库函数printf()默认就是使用stdout输出数据的,用户也可以通过重新设置标准的I/O,把程序的输出输入结果定向到其他设备上。
四、缓冲
标准的文件I/O提供了缓冲机制,目的在于减少外部设备的读取次数,同时可以提高程序的读写性能,标准库提供了三种缓冲类型:
全缓冲:全缓冲通常用在磁盘文件中,只有当缓冲写满之后才会把缓冲的数据储存到磁盘中;
行缓冲:行缓冲顾名思义就是以行为单位操作缓冲区,使用这种缓冲方式当系统遇到换行符的时候会执行I/O操作,这是终端常用的缓冲模式;
不带缓冲:标准的I/O不缓冲任何字符。如果使用不带缓冲的流,相当于直接把数据通过系统调用写到设备上(后面会介绍write系统调用)如标准错误输出stderr就是不带缓冲的。
ANSI文件I/O库在stdio.h头文件中为用户提供了两个设置缓冲的函数接口:
void setbuf(FILE *fp, char *buf);
int setvbuf(FILE *fp, char *buf, intmode, siez_t size);
setbuff()函数可以打开或者关闭一个I/O流使用缓冲。fp参数传入一个I/O流的文件指针,buf参数指向一个BUFSIZ(在stdio.h头文件中定义)大小的缓冲,在设置buf参数后标准库会为I/O流设置一个全缓冲。如关闭一个缓冲,设置buf参数为NULL即可;
举例:
char *buf = (char*)malloc(BUFSIZ);
setbuf(stdout,buf);
printf("Set STDOUT full buffer OK!\n");
setbuf(stdout,NULL);
printf("Set STDOUT no buffer OK!\n")
需要注意的是在设置一个文件的缓冲时需要打开文件才能设置
setbuff()函数是依靠mode参数来实现为I/O流设置指定类型的缓冲,mode的参数如下:
_IOFBF:全缓冲;
_IOLBF:行缓冲;
_IONBF:不带缓冲;
其中如果指定了不带缓冲,setbuf()函数会忽略buf和size参数;如果setbuf()函数的buf参数为空,mode参数在仍然设置全缓冲或者行缓冲时,库会自动为指定的流设置一个适当长度的缓冲;
五、打开关闭文件
ANSI C文件库定义了打开文件的函数fopen()和关闭文件的函数fclose(),定义如下:
FILE *FOPEN(const char *path, const char *mode);
int fclose(FILE * stream);
打开关闭文件的函数都定义在stdio.h的头文件中,fopen()函数用来打开一个文件,path参数指定文件路径mode参数指定打开方式 fopen()参数如下:
mode参数 | 说明 |
---|---|
r或rb | 为读打开文件 |
w或wb | 为写打开文件,并把文件长度置0(清空文件) |
a或ab | 在文件结尾添加打开 |
r+或r+或rb+ | 为读和写打开 |
w+或w+b或wb+ | 为写打开文件,并把文件大小置0(清空文件) |
a+或a+b或ab+ | 在文件结尾读写打开 |
在文件结尾读写打开mode参数将文件分为读、写、读写3种方式,另外参数中的+也有作用,表示在文件打开后在最后添加数据,这种方式不会破坏原来的文件内容当打开一个文件成功后fopen()函数会返回一个FILE类型的文件指针,这个指针是关键,后面的操作都需要用到。
如果文件打开失败,会返回NULL,这个可作为是否成功打开文件的判断依据;在操作完文件需要将打开的文件关掉,fclose函数关闭文件成功后会返回一0,如果关闭失败会返回常量EOF,并且设置错误代码到系统库的ERROR全局变量。
关闭文件不只是一种好的习惯,更重要的是文件流可能带有缓冲,只有成功关闭了文件以后才能确保数据被正确写入,否则可能造成数据丢失;
六、读写文件
一旦文件打开成功,我们就可以进行文件操作了,ANSI C 文件库提供了3种不同类型的文件读写函数:
1、每次一个字符的I/O。一次读写一个字符,如果需要带有缓冲的流,由标准I/O函数处理缓冲;
2、每次一行的I/O。每次读写一行的数据,换行符\n标志着一行的结束
3、成块数据的I/O。每次读写指定大小的数据,可以指定数据块的大小,以及数据块的数量,这种方式常用在读写二进制文件中;
每次一个字符的文件读取:
int getc(FILE *stream);
int fgetc(FILE *stream);
int getchar(void);
getc函数和fgetc函数的作用是相同的,参数stream指向一个文件的文件流指针,返回从文中读取的一个字符,若读取失败,返回EOF;
以上即是本篇文章的全部内容,欢迎在下方留言板评论留言!
往期回顾
01 | |
02 | |
03 | |
04 | |