![](https://i-blog.csdnimg.cn/blog_migrate/0d82592a5130c40eb00324918bf830a9.gif)
思维导图:
![](https://i-blog.csdnimg.cn/blog_migrate/8994f576efca598f3473b332518cb4b2.png)
第10章 对文件的输入输出
10.1 C文件的有关基本知识
凡是用过计算机的人都不会对“文件”感到陌生,大多数人都接触过或使用过文件,例如:写好一篇文章把它存放到磁盘上以文件形式保存;编写好一个程序,以文件形式保存在磁盘中;用数码相机照相,每一张照片就是一个文件;随电子邮件发送的“附件”就是以文件形式保存的信息。需要时就从文件读取信息。在程序中使用文件之前应了解有关文件的基本知识。
10.1.1 什么是文件
文件有不同的类型,在程序设计中,主要用到两种文件:
-
程序文件: 包括源程序文件(后缀为
.c
)、目标文件(后缀为.obj
)、可执行文件(后缀为.exe
)等。这种文件的内容是程序代码。 -
数据文件: 文件的内容不是程序,而是供程序运行时读写的数据,如在程序运行过程中输出到磁盘(或其他外部设备)的数据,或在程序运行过程中供读入的数据。如一批学生的成绩数据、货物交易的数据等。本章主要讨论的是数据文件。
在以前各章中所处理的数据的输入和输出,都是以终端为对象的,即从终端的键盘输入数据,运行结果输出到终端显示器上。实际上,常常需要将一些数据(运行的最终结果或中间数据)输出到磁盘上保存起来,以后需要时再从磁盘中输入到计算机内存。这就要用到磁盘文件。
为了简化用户对输入输出设备的操作,使用户不必去区分各种输入输出设备之间的区别,操作系统把各种设备都统一作为文件来处理。从操作系统的角度看,每一个与主机相连的输入输出设备都看作一个文件。例如,终端键盘是输入文件,显示屏和打印机是输出文件。
文件的定义
文件(file)是程序设计中一个重要的概念。所谓“文件”一般指存储在外部介质上数据的集合。一批数据是以文件的形式存放在外部介质(如磁盘)上的。操作系统是以文件为单位对数据进行管理的,也就是说,如果想找存放在外部介质上的数据,必须先按文件名找到所指定的文件,然后再从该文件中读取数据。要向外部介质上存储数据也必须先建立一个文件(以文件名作为标志),才能向它输出数据。
流的概念
输入输出是数据传送的过程,数据如流水一样从一处流向另一处,因此常将输入输出形象地称为流(stream),即数据流。流表示了信息从源到目的端的流动。在输入操作时,数据从文件流向计算机内存;在输出操作时,数据从计算机流向文件(如打印机、磁盘文件)。文件是由操作系统进行统一管理的,无论是用Word打开或保存文件,还是C程序中的输入输出都是通过操作系统进行的。“流”是一个传输通道,数据可以从运行环境(有关设备)流入程序中,或从程序流至运行环境。
C语言中的文件
C语言把文件看作一个字符(或字节)的序列,即由一个一个字符(或字节)的数据顺序组成。一个输入输出流就是一个字符流或字节(内容为二进制数据)流。
C的数据文件由一连串的字符(或字节)组成,而不考虑行的界限,两行数据间不会自动加分隔符,对文件的存取是以字符(字节)为单位的。输入输出数据流的开始和结束仅受程序控制而不受物理符号(如回车换行符)控制。这就增加了处理的灵活性。这种文件称为流式文件。
10.1.2 文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。文件标识包括三部分:(1) 文件路径;(2) 文件名主干;(3) 文件后缀。
文件路径
文件路径表示文件在外部存储设备中的位置。如:
D:\CC\temp\file1.dat
这里表示 file1.dat
文件存放在D盘中的CC目录下的temp子目录下面。
文件名主干和后缀
文件名主干的命名规则遵循标识符的命名规则。文件后缀用来表示文件的性质,如:doc
(Word生成的文件)、txt
(文本文件)、dat
(数据文件)、c
(C语言源程序文件)、cpp
(C++源程序文件)、for
(FORTRAN语言源程序文件)、pas
(Pascal语言源程序文件)、obj
(目标文件)、exe
(可执行文件)、ppt
(电子幻灯文件)、bmp
(图形文件)等。
理解与应用
文件名不仅仅是一个标签,它包含了文件存储位置的信息,这使得计算机能够准确找到并处理文件。在开发应用程序时,正确处理文件路径和文件名对于文件的读取和写入是至关重要的。
实际应用中的例子
例子3:检查文件是否存在
编写一个C程序检查给定路径的文件是否存在:
#include <stdio.h>
int main() {
FILE *file;
char *filename = "D:\\CC\\temp\\file1.dat";
file = fopen(filename, "r");
if (file) {
printf("File %s exists.\n", filename);
fclose(file);
} else {
printf("File %s does not exist.\n", filename);
}
return 0;
}
小结
正确理解文件名的结构和含义,可以帮助我们在编写程序时更有效地处理文件操作,确保数据能够正确读写和存储。
10.1.3 文件的分类
根据数据的组织形式,数据文件可分为ASCII文件和二进制文件。
ASCII文件
ASCII文件又称文本文件(text file),每一个字节存放一个字符的ASCII代码。字符一律以ASCII形式存储,这种文件便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间(在二进制形式与ASCII码之间转换)。
二进制文件
二进制文件不加转换地输出到外存,可以认为它是存储在内存的数据的映像,所以也称之为映像文件(image file)。二进制形式输出数值可以节省外存空间和转换时间,把内存中的存储单元内容原封不动地输出到磁盘(或其他外部介质)上。
理解与应用
根据具体需求选择合适的文件类型非常重要。例如,处理人类可读数据时使用ASCII文件,而需要高效存储和快速读写时则使用二进制文件。
实际应用中的例子
例子4:写入和读取二进制文件
编写一个C程序,将一个整数数组写入二进制文件,并从文件中读取该数组:
#include <stdio.h>
int main() {
FILE *file;
int numbers[] = {10, 20, 30, 40, 50};
int read_numbers[5];
// 写入二进制文件
file = fopen("numbers.bin", "wb");
if (file == NULL) {
perror("Error opening file");
return -1;
}
fwrite(numbers, sizeof(int), 5, file);
fclose(file);
// 读取二进制文件
file = fopen("numbers.bin", "rb");
if (file == NULL) {
perror("Error opening file");
return -1;
}
fread(read_numbers, sizeof(int), 5, file);
fclose(file);
// 输出读取到的数据
for (int i = 0; i < 5; i++) {
printf("%d ", read_numbers[i]);
}
return 0;
}
小结
了解ASCII文件和二进制文件的区别和各自的优缺点,可以帮助我们在编写程序时做出最佳选择,从而提高程序的效率和灵活性。
10.1.4 文件缓冲区
ANSI C标准采用“缓冲文件系统”处理数据文件。系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区,然后再从缓冲区逐个地将数据送到程序数据区。
理解与应用
文件缓冲区的使用可以显著提高文件读写操作的效率。通过缓冲区的机制,可以减少直接磁盘I/O操作的次数,从而提高性能。
实际应用中的例子
例子5:演示文件缓冲区的使用
编写一个C程序,演示如何使用文件缓冲区进行高效的数据读写:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
char buffer[512];
file = fopen("largefile.txt", "w");
if (file == NULL) {
perror("Error opening file");
return -1;
}
// 设置缓冲区
if (setvbuf(file, buffer, _IOFBF, sizeof(buffer)) != 0) {
perror("Failed to set buffer");
return -1;
}
for (int i = 0; i < 1000; i++) {
fprintf(file, "This is line %d\n", i);
}
fclose(file);
return 0;
}
小结
使用文件缓冲区可以有效提高文件读写操作的性能,特别是在处理大文件或频繁的读写操作时尤为明显。
10.1.5 文件类型指针
在缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的有关信息(如文件的名字、文件状态及文件当前位置等)。这些信息保存在一个结构体变量中,该结构体类型由系统声明,取名为 FILE
。
理解与应用
通过文件指针,可以方便地访问文件的各种信息和进行文件操作。文件指针不仅指向外部文件,还指向内存中的文件信息区,通过文件信息区中的信息可以高效管理和操作文件。
实际应用中的例子
例子6:使用文件指针进行文件操作
编写一个C程序,演示如何使用文件指针进行文件的打开、读写和关闭操作:
#include <stdio.h>
int main() {
FILE *file;
char *filename = "example.txt";
// 打开文件
file = fopen(filename, "r");
if (file == NULL) {
perror("Error opening file");
return -1;
}
// 读取文件内容并输出
char ch;
while ((ch = fgetc(file)) != EOF) {
putchar(ch);
}
// 关闭文件
fclose(file);
return 0;
}
小结
理解文件指针的概念和使用方法,可以帮助我们更灵活和高效地进行文件操作。在实际编程中,通过文件指针可以方便地管理和操作文件,提升程序的可维护性和扩展性。
![](https://i-blog.csdnimg.cn/blog_migrate/c8961dee30f935fd0699265e918fc667.png)