在Unix中,当我们使用标准IO库来进行文件操作时,我们就对该文件创建了一个文件流。每一个文件流都具有缓冲区,可以用来缓存从文间中读取(写入)的内容,缓冲可以分为三种方式:
- 全缓冲(fully buffered),当缓冲区全部填满时才调用系统函数执行读写操作。
- 行缓冲(line buffered),当缓冲区内读取到换行符,或缓冲区被写满时才调用系统函数执行读写操作。
- 无缓冲(unbuffered),没有缓冲区,每次根据要求调用系统函数进行单个字符的连续读取操作。
可以通过调用fflush函数对指定文件流缓冲区进行强制刷新,调用系统函数执行相应读写操作,并清空缓冲区中内容。setbuf函数和setvbuf函数可以修改指定文件流的缓冲方式及缓冲区位置,其函数原型为:
void setbuff ( FILE *fp, char *buf); void setvbuf ( FILE *fp, char *buf, int mode, size_t size);
参数fp为指定文件流,buf为指定缓冲区,buf的长度必须与BUFSIZE(宏定义于stdio.h文件)保持一致。在setbuff函数中,当buf为NULL时,文件流缓冲方式将调整为无缓冲(unbuffered);当buf不为NULL时,文件流缓冲方式将调整为全缓冲或行缓冲。在函数setvbuff中,缓冲方式由参数mode指定,当参数buf为NULL时,将由编译器为文件流fp自动分配一段内存空间作为缓冲区,缓冲区大小为size。
文件流FILE常以结构体的形式定义,该结构中包含文件描述符、缓冲区指针、缓冲区大小、缓冲区中数据长度、错误标志位、文件结束标志位等信息。
打开文件可使用fopen、freopen、fdopen函数。当使用freopen函数时,可将文件打开至某一文件流中,加入该文件流中已存在某一打开的文件,则该文件被关闭,新文件被打开。函数fdopen用于打开某一文件描述符指定的文件。当使用"w"方式打开文件时,若该文件已存在,则文件内容将被清空,若该文件不存在,则新建该文件。可使用fclose函数关闭已打开的文件。文件被关闭时,缓冲区的内容将被写入至文件中。getc、fgetc、fgets函数常用于读取文件中的内容,fgets函数一次读取一行的内容。类似的putc、fputc、fputs函数用于像文件中写入内容,fputs函数一次写入一行内容。ungetc函数可将字符写回至文件流缓冲区中(即回退操作),写回的字符位于缓冲区中第一个读取字符的位置。getc与putc函数在标准中可以以宏定义的形式实现,因此这两个函数不具有内存地址,无法进行取地址操作。具体实现由编译器而定。使用标准IO库操作文件流时,由于缓冲区的存在,文件读写操作(read、write函数调用)次数将大大减少,能够大幅度提升文件读写速度,使程序运行时瓶颈由大量的文件操作转移至应用逻辑处理中。
标准IO库中,使用一下函数对二进制文件进行操作:
size_t fread(void *ptr, size_t size, size_t nobj, FILE *fp); size_t fwrite(void *ptr, size_t size, size_t nobj, FILE *fp);
参数size为操作中每个操作单元的大小,参数nobj为需要操作的单元个数。如:
size_t length = 0; char buff[MAXBUF]; length = fread(buff, sizeof(char), sizeof(buff), stdin);//由标准输入读取MAXBUF个char元素。
ftell、fseek函数与tell、seek、lseek函数作用类似,rewind函数可将文件流所对应的文件偏移量(offset)重置至文件头。当需要使用系统函数调用时,可使用fileno函数从文件流中获取相应的文件描述符。
格式化输出函数包括printf、fprintf、sprintf、snprintf。与之对应的,格式化输入函数包括scanf、fscanf、sscanf。函数snprintf和sprintf的区别在于,snprintf函数可指定一次性所读取到字节数,而sprintf函数需由使用者确保目标数组足以装下所有可能读入的数据。
格式化输出函数的转意部分可由五部分构成,其格式为:
%[flag][fldwidth][precision][lenmodifier]convtype
flag表示前缀,为'+'、'-'、' '、'#'、'0'之一,fldwidth为有效长度,precision为精度(小数点精确至多少位),lenmodifier为参数长度(单字节、双字节、四字节等),convtype为读取类型(八进制、十进制、十六进制、浮点数、字符、字符串等)。当fldwidth或precision为星号('*')时,将从读取一个参数并将参数值作为fldwidth或precision值。
格式化输入函数的转意部分可由四部分构成,其格式为:
%[*][fldwidth][lenmodifier]convtype
星号表示按相应格式读取元素但并不保存(跳过该元素),fldwidth、lenmodifier、convtype与格式化输出用法相同。
ISO C标准提供了tmnam、tmpfile来新建二进制临时文件,XSI对ISO标准进行了扩展,出现tempnam与mkstemp函数。tempnam与mkstemp函数可指定临时文件名及文件路径。tmnam与tempnam函数只是单纯的由系统生成一个唯一的临时文件名,并将文件名作为返回值,并不创建临时文件。tmpfile与mkstemp函数创建一个临时文件,该文件在进程结束时自动关闭。
tmpfile的一般化实现方法为:先由tmnam函数生成一个临时文件名,再使用该文件名创建一个新文件(creat或open函数),对该文件实行unlink操作。由于临时文件已被打开,unlink操作并不会强制关闭该文件,用户仍然可以对文件执行操作,但是该文件本身已不可见。进程结束后,由于临时文件被关闭,文件内容被自动删除。
来源:https://www.cnblogs.com/pgx1030/archive/2012/06/18/2552768.html