与操作系统独立,只能操作常规文件,有缓冲区
常规文件:ASCII码文件(文本文件)、二进制文件
缓冲区:减少用户和内核切换的次数,减小系统开销。当对文件进行操作时,缓冲区才会被开辟。当进程结束时自动调用fclose(),关闭已打开的文件,刷新缓冲区。
全缓冲:4k字节,用于标准文件操作,当缓冲区满的时候给内核。
行缓冲:1k字节,用于标准输入输出,当缓冲区遇到‘\n’时给内核。
不带缓冲:0字节,用于标准出错,数据不经过缓冲区,直接给内核。
内核中有高速缓存,定时刷新至硬盘。
描述 文件描述符int 文件描述符对应的宏 文件指针FILE*
标准输入 0 STDIN_FILENO stdin
标准输出 1 STDOUT_FILENO stdout
标准错误 2 STDERR_FILENO stderr
int fflush(FILE *fp); 用于将缓冲区中的数据实时刷新至内核。
FILE *fopen(const char *path,const char *mode);
FILE *fdopen(int fd,const char *mode); //联系流与文件描述符
FILE *freopen(const char *path,const char *mode,FILE *stream); //用于重定向
int fclose(FILE *stream);
当一个进城正常终止时(直接调用exit函数,或从main函数返回),系统会自动调用fclose()函数,刷新所有缓冲区,所有打开的标准I/O流都被关闭。
为了编程规范,使用文件后,一定要显式的调用fclose()。
mode参数:
r或rb 打开只读文件,该文件必须存在。
r+或rb+ 打开可读写的文件,该文件必须存在。
w或wb 打开只写文件,若文件存在则清空。若文件不存在则创建该文件。
w+或wb+ 打开可读写文件,若文件存在则清空,若文件不存在则创建该文件。
a或ab 以附加方式打开只写文件,若不存在则创建,若文件存在,写入的数据追加到文件尾,即原先内容被保留。
a或ab+ 以附加方式打开可读写文件,若不存在则创建,若文件存在,写入的数据追加到文件尾,即原先内容被保留。
b 表示以二进制方式打开文件。
二进制和文本模式的区别
1.在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。
2.在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
每次一个字符的I/O:如果流是带缓冲的,标准I/O函数处理所有缓冲。
int fgetc(FILE *stream); 文件结尾或出错都返回EOF
while(!feof(fp)&&!ferror(fp))
{
ch = fgetc(fp);
if(ch == EOF) break;
printf("%c",ch);
}
int fputc(int c,FILE *stream);
int getc(FILE *stream);
int putc(FILE *stream);
实现为宏,从流中读或写。
int getchar(void); 从终端读 stdin
int putchar(int c); 输出到终端 stdout
实现为宏
检查文件出错函数
int feof(FILE *stream);
int ferror(FILE *stream);
int clearerr(FILE *stream);
每次一行的I/O:每行都以‘\n‘结束
char *fgets(char *s,int size,FILE *stream);已处文件尾端或出错返回NULL。
fgets一次只能从文件读取一行(一行最大1024个字节),在文本文件中,每行最后都是‘\n’,fgets会自动读取最后的换行符,所以打印时不需加‘\n‘。
当用fgets读取n个字节的数据时,只会返回n-1个字符,最后一个放‘\0’。
while(fgets(str,100,fp1) != NULL)
{
fputs(str,fp2);
}
int fputs(const char *s,FILE *stream);
char *gets(char *s);int puts(const char *s);
直接I/O:用于读写块或结构体
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
从流stream中读取size*nmemb个字节到ptr开始的地址空间。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
定位流:
int fseek(FILE *stream, long offset, int whence); 用于设定流的文件位置。offset为正向后偏移,为负向开头偏移。whence参数为 SEEK_SET(开头)/SEEK_CUR(当前)/SEEK_END(结束)。
long ftell(FILE *stream); 获取当前的文件位置。
void rewind(FILE *stream); 用于设定流的文件位置为文件开始。