2.3 打开和关闭流
以下函数用于打开和关闭一个流。
#include <stdio.h>
FILE * fopen (const char *pathname, const char *opentype);
int fclose (FILE *stream);
FILE * freopen (const char *pathname, const char *opentype, FILE *stream);
fopen()打开由pathname指定的文件并创建一个与之相连的流。如果该文件不存在,则创建一个新文件。如果打开文件成功,它返回指向此流的指针,否则返回空指针NULL。
opentype参数是一字符串,它控制文件打开的方式,其值只能是下述字符串之一:
"r":为读而打开一个已存在的文件,文件位置定位于文件开始。
"w":为写而打开一个文件。如果文件存在,则将它的长度截为0,也即文件将被重新写过;如果文件不存在,则创建一个新文件。
"a":为在文件尾添加内容而打开文件。若文件存在,原来的内容不变且输出添加在文件的末尾;否则,创建一个新文件。
"r+":为更新(既读又写)而打开一个已存在的文件,文件原有内容不变,文件位置定位于文件开始。
"w+":为更新(既读又写)而打开一个文件,若文件已存在,其长度被截至0;否则,创建一个新文件。
"a+":为更新(既读又写)而打开一个文件,若文件已存在,原内容不变;否则,创建一个新文件。用于读的初始文件位置定位于文件开始,但输出总是添加在文件的末尾。
其中,字母r、w和a分别代表read、write和append。字符“+”指明为更新而打开一个文件,当以这种方式打开一个文件时,对它既可写也可读。
以添加方式("a"或"a+"方式)打开的文件,不管文件的当前位置如何,所写出的数据总是顺序地附加在文件的末尾,因此不可能覆盖文件原来的内容。其文件位置只用于控制从文件中读数据。
打开的流通过调用fclose()来关闭。fclose()关闭参数stream指定的流,并中断与对应文件的连接。在流被关闭之前,所有缓冲的输出将被写出。关闭一个流后就不能再对它进行任何操作。
fclose()调用成功返回0,否则返回EOF并置errno指明错误。
当调用fclose()关闭一输出流时,对错误情形进行检查很重要,因为此时可能检测到真实的错误。例如,当fclose()将缓冲区中剩余的数据写出时,它可能得到磁盘空间已满的错误,如果不检测的话,就有可能丢失文件的内容。
进程从main()退出或调用exit()正常终止时(5.4节),所有打开的流都将自动被关闭。但为了确保输出数据的完整性,编写程序时仍然应当在进程结束前明显地调用fclose()。因为当进程以其他非正常方式终止时,例如调用abort()流产程序(5.4.3节)或由于致命信号(7.2节),文件没有正常关闭,输出缓冲区中的数据将不会被写出,从而可能导致文件不完整。2.7节会更详细地讲述流缓冲的问题。
freopen()重新打开pathname指定的文件,它的作用类似于fclose()和fopen()的合并。如果stream指定的流是打开的,它首先关闭该流,忽略任何错误,然后按opentype所给方式如同fopen()一样打开参数pathname指定的文件,并使之与stream给定的同一个流相连。freopen()调用成功返回指向流的指针,否则返回NULL并置errno指明错误。
freopen()一般用于连接标准流stdin、stdout、stderr至一个我们选择的文件。它对那种难以对标准流进行编程的程序很有用。
例2-1 程序2-1是个简单的示例程序,它打开一个文件写入若干数据之后再重新打开此文件读出所写的数据。