C语言的流和文件
来源:互联网 发布:javascript语法大全 编辑:程序博客网 时间:2024/05/22 06:47
流是一个连接输入源与输入缓冲区、输出缓冲区与输出目的地的管道。如果不使用缓冲区,流则直接连通输入源和输出目的地。磁盘上的文件是常用的输入源和输出目的地。
文件指针
C程序中的流是通过文件指针访问的,其类型为FILE *
。FILE
是在stdio.h
中定义的类型。虽然操作系统通常会限制在任意时刻打开的流的数量,但可以声明任意数量的FILE *
类型变量。
在stdio.h
中提供了3个文件指针stdin
,stdout
和stderr
,分别用以访问标准输入流、标准输出流和标准错误流。标准输入流的输入源为键盘,标准输出流和标准错误流的输出目的地为屏幕。
stdin
标准输入 键盘 stdout
标准输出 屏幕 stderr
标准错误 屏幕scanf
、printf
、putchar
、getchar
、puts
和gets
都是通过stdin
输入,通过stdout
输出的。
某些操作系统通过重定向机制改变标准流的默认含义。输入重定向将stdin
访问的流的输入源由键盘改为文件,输出重定向将stdout
访问的流的输出目标由屏幕更改为文件。在Linux
系统中,输入重定向是使用<
后接输入文件名实现的,而输出重定向是使用>
后接输出文件名实现的,同时还可以将输出重定向和输入重定向合并使用,其使用格式为:
运行程序名 <输入文件名运行程序名 >输出文件名运行程序名 <输入文件名 >输出文件名
为了避免在重定向时将错误信息也输入到文件中,使用stderr
输出错误信息。
/************************************* * redirect.c * * * * 输入输出重定向 * *************************************/#include <stdio.h>int main(){ int x = 0; int y = 0; printf("输入两个整数: "); scanf("%d%d", &x, &y); printf("x = %d, y = %d\n", x, y); return 0;}
文本文件和二进制文件
文件的类型有两种,一种为文本文件,一种为二进制文件。文本文件中字节表示字符,而二进制文件中,字节并不一定表示字符,字节组可以表示整型、浮点型等类型数据的二进制形式。
根据实际需要,选择合适的文件类型。当需要支持在屏幕上展示文件的内容时,应使用文本文件。
文件操作
打开文件
打开访问文件的流(简称打开文件)的函数的原型为:
FILE *fopen(const char *filename, const char *mode);
第一个参数为要打开的文件名的字符串(文件名可能包括路径信息,以明确地指定文件,可以是相对路径也可以是绝对路径),第二个参数是模式字符串,说明对文件执行的操作模式。fopen
返回一个指针变量,需要将其存放在一个指针变量中,至少供关闭流时使用。如果因指定的文件不存在或无权访问文件等原因而无法打开文件,fopen
将返回一个空指针。注意始终要测试fopen
的返回值。
fopen
可以使用的模式字符串如下表所示:
"r"
打开文本文件用于读 "rb"
打开二进制文件用于读 "w"
打开文件用于写,若文件不存在,创建新文件 "wb"
打开二进制文件用于写,若文件不存在,创建新文件 "a"
打开文件用于追加内容,若文件不存在,创建新文件 "ab"
打开二进制文件用于追加内容,若文件不存在,创建新文件 "r+"
打开文件用于读和写,从文件头开始 "r+b"
或"rb+"
打开二进制文件用于读和写,从文件头开始 "w+"
打开文件用于读和写,如果文件已存在则覆盖其内容 "w+b"
或"wb+"
打开二进制文件用于读和写,如果文件已存在则覆盖其内容 "a+"
打开文件用于读和写,以追加的方式写入 "a+b"
或"ab+"
打开文件用于读和写,以追加的方式写入关闭文件
关闭文件的函数的原型为:
int fclose(FILE *stream);
fclose关闭指向文件的流。该函数的参数为指向某个以打开的流的文件指针(不能是标准流,它们自动被打开,不能并关闭)。如果成功关闭了文件流,则返回0,否则返回错误代码EOF
。
/************************************* * open_close_a_file.c * * * * 打开关闭文件流 * *************************************/#include <stdio.h>int main(){ FILE *fp = NULL; fp = fopen("test.txt", "r"); if (fp == NULL) printf("文件test.txt不存在!\n"); else fclose(fp); FILE *fp2 = NULL; fp2 = fopen("test.txt", "w"); if (fp2 == NULL) { printf("文件test.txt不存在!\n"); return 0; } fclose(fp2); return 0;}
重定向文件
freopen
函数为已打开的流指定一个不同的输入源文件或目标文件。freopen
的函数原型为:
FILE *freopen(const char *filename, const char *mode, FILE *stream);
freopen
常用以为标准流重定向,包括输入重定向、输出重定向或错误输出重定向。它实际上是先关闭stream
原先指向的流,在使stream
重新关联新打开的流。该函数的返回值是第三个实际参数,如果无法打开新的文件,则返回空指针。
/************************************* * redirect_stream.c * * * * 利用freopen重定向流 * *************************************/#include <stdio.h>int main(){ FILE *fp = NULL; fp = fopen("test.txt", "w"); freopen("test2.txt", "w", fp); fprintf(fp, "现在流指向test2.txt\n"); fclose(fp); return 0;}
临时文件
程序中经常要使用临时文件,C语言的stdio
库提供了两个函数来处理临时文件,它们分别为tmpfile
函数和tmpnam
函数,其原型分别为:
FILE *tmpfile(void);char *tmpnam(char *s);
tmpfile
函数产生临时文件,该文件要么直接在程序运行过程中被关闭而销毁,要么在程序终止时自动销毁。tmpfile
函数的返回值是一个指针变量,如果创建临时文件失败,则返回空指针。使用tmpfile
的缺点是无法知道文件名,并且不能让其成为永久文件,解决这些问题的方法是用fopen
来创建临时文件。
创建临时文件时需要生成临时文件名,tmpnam
就提供这样的功能。如果传入tmpnam
的是空指针,那么tmpnam
会创建一个静态变量来保存创建的文件名,并返回该变量的指针,如果传入的是一个字符数组,则会将生成的文件名复制到该字符数组内,同时也会返回静态变量的指针。<stdio.h>
中定义了宏L_tmpnam
,指定了临时文件名的字符数组长度。在使用tmpnam
函数时请确保出入的字符数组至少包含L_tmpnam
个字符,且避免频繁地调用该函数,TMP_MAX
宏定义了程序执行期间tmpnam
函数产生的临时文件名的最大数量。
/************************************* * tmp_file_name.c * * * * 利用tmpfile和tmpname生成临时文件和* * 文件名 * *************************************/#include <stdio.h>#include <stdlib.h>int main(){ FILE *fp = NULL; fp = tmpfile(); fprintf(fp, "Hello World"); system("ls -la"); unsigned long tmpNamLength = L_tmpnam; printf("临时文件的字符数组长度: %lu\n", tmpNamLength); char tmpFileName[L_tmpnam]; tmpnam(tmpFileName); printf("生成的随机文件名为%s\n", tmpFileName); char *tmpFileName2 = tmpnam(NULL); printf("生成的第二个随机文件名为%s\n", tmpFileName2); unsigned long tmpFileNum = TMP_MAX; printf("程序执行期间产生的最多%lu个随机文件名\n", tmpFileNum); return 0;}
编译过程中有一个警告信息,提示tmpnam函数安全性差,建议使用mkstemp
函数。
文件缓冲
缓冲是解决磁盘驱动器和内存速度不一致的有效方式。缓冲的使用机制如下:写入流的数据实际是存储在内存的缓冲区内,当缓冲区满或流关闭时,缓冲区会将被“清洗”以将数据写入实际的输出设备。输入流类似地从输入设备中获得数据并放在缓冲区中,内存直接从缓冲区读取数据。文件流的函数会自动处理缓冲操作,但C语言也提供了fflush
函数、setbuf
函数和setvbuf
函数主动执行缓冲相关操作,它们的原型分别为:
int fflush(FILE *stream);int setbuf(FILE *stream, char *buf);int setvbuf(FILE *stream, char *buf, int node, size_t size);
通过fflush
函数可以频繁地清洗缓冲区,而不需要等缓冲区满或文件关闭时才执行。当实际参数为文件指针,则清洗该文件指针访问的流的缓冲区,若实际参数为NULL
,则清晰所有输出流的缓冲区。如果调用成功,则返回0
,否则返回EOF
。
setvbuf
用以改变缓冲流的方式,并且允许控制缓冲流的大小和位置。setvbuf
的第二个参数指定期望缓冲区的地址,第三个参数说明了期望缓冲区的类型,包括以下几项:
- _IOFBF (满缓冲)。当缓冲区为空时,从流中读入数据,当缓冲区满时,向流写入数据。
- _IOLBF(行缓冲)。每次从流向缓冲区读入或从缓冲区向流写入一行数据。
- _IONBF(无缓冲)。不使用缓冲区直接从流读入输入或直接向流写入数据。
第四个参数指定缓冲区内字节的数量,较大的缓冲区提高性能,较小的缓冲区节约空间。
setbuf
是一个过期的函数,用以设定缓冲模式的默认值和大小,不建议使用。
删除和重命名文件
可以利用下列函数删除或重命名文件,执行基本的文件管理操作:
int remove(const char *filename);int rename(const char *old, const char *new);
如果函数调用成功,则返回0,否则返回非零值。确保在重命名之前关闭访问文件的流。
参考文献
1.K.N. King 著,吕秀峰 译. C语言程序设计-现代方法. 人民邮电出版社
2. http://www.360doc.com/content/12/1114/16/3398926_247829293.shtml
3. http://www.docin.com/p-293383919.html
- C语言的流和文件
- C语言函数库和文件
- C语言函数库和文件
- C语言指针和文件笔记
- 流和文件的区别
- 用C语言编写一个HTTP协议的目录浏览和文件下载服务器
- linux下的C语言快速学习—进程和文件
- 如何使用c语言递归地列出linux系统的所有目录和文件
- c 缓冲和文件
- 《C语言深度刨析》整理--函数和文件
- C语言学习-结构体和文件操作
- C语言文件指针和文件描述符
- C语言文件指针和文件描述符相互转换
- C语言写递归复制文件夹和文件
- 【C语言】通讯录:动态开辟内存版和文件版本
- 关于c中文件包含和文件工程的意思
- 流的分类和文件的读写
- 流和文件描述符的关系
- Spring MVC form handling annotation example
- visualgdb windows linux 跨平台编译
- 常用Windows消息、常量命名参考
- Linux服务器部署系列之一—Apache篇(上)
- Mac 安装Django
- C语言的流和文件
- 应用宝使用绑定iOS下载
- JavaScript break跳出多重循环
- Container With Most Water
- jQuery时间轴特效
- android 内存管理工具 DDMS
- anroid OpenGL ES之 向shader传递数据
- ubuntu ssh拷贝文件
- Poj 天梯初级题目总结