文章目录


文件相关概念

文件的概念

一个文件通常就是磁盘上一段命名的存储区。

但是对于操作系统来说,文件就会更复杂一些。例如,一个大文件可以存储在一些分散的区段中,或者还会包含一些操作系统可以确定其文件类型的附加数据,但是这些是操作系统,而不是我们程序员所要关心的事情。我们应该考虑如何在C程序中处理文件。

流的概念

流是一个动态的概念,可以将一个字节形象地比喻成一滴水,字节在设备、文件和程序之间的传输就是流,类似于水在管道中的传输,可以看出,流是对输入输出源的一种抽象,也是对传输信息的一种抽象。

C语言中,I/O操作可以简单地看作是从程序移进或移出字节,这种搬运的过程便称为流(stream)。程序只需要关心是否正确地输出了字节数据,以及是否正确地输入了要读取字节数据,特定I/O设备的细节对程序员是隐藏的。

文本流

文本流,也就是我们常说的以文本模式读取文件。文本流的有些特性在不同的系统中可能不同。

例如:

  1. 其中之一就是文本行的最大长度。标准规定至少允许254个字符。
  2. 另一个可能不同的特性是文本行的结束方式。例如在Windows系统中,文本文件约定以一个回车符和一个换行符结尾。但是在Linux下只使用一个换行符结尾。

标准C把文本定义为零个或者多个字符,后面跟一个表示结束的换行符(\n)。对于那些文本行的外在表现形式与这个定义不同的系统上,库函数负责外部形式和内部形式之间的翻译。例如,在Windows系统中,在输出时,文本的换行符被写成一对回车/换行符。在输入时,文本中的回车符被丢弃。这种不必考虑文本的外部形势而操纵文本的能力简化了可移植程序的创建。

二进制流

二进制流中的字节将完全根据程序编写它们的形式写入到文件中,而且完全根据它们从文件或设备读取的形式读入到程序中。它们并未做任何改变。这种类型的流适用于非文本数据,但是如果你不希望I/O函数修改文本文件的行末字符,也可以把它们用于文本文件。

c语言在处理这两种文件的时候并不区分,都看成是字符流,按字节进行处理。

我们程序中,经常看到的文本方式打开文件和二进制方式打开文件仅仅体现在换行符的处理上。

比如说,在widows下,文件的换行符是​​\r\n​​,而在Linux下换行符则是​​\n​​。

当对文件使用文本方式打开的时候,读写的windows文件中的换行符​​\r\n​​会被替换成​​\n​​读到内存中,当在windows下写入文件的时候,​​\n​​被替换成​​\r\n​​再写入文件。

如果使用二进制方式打开文件,则不进行​​\r\n​​和​​\n​​之间的转换。 那么由于Linux下的换行符就是\n,所以文本文件方式和二进制方式无区别。

文件的操作

文件流总览

标准库函数是的我们在C程序中执行与文件相关的I/O任务非常方便。下面是关于文件I/O的一般概况。

1.程序为同时处于活动状态的每个文件声明一个指针变量,其类型为​​FILE*​​。这个指针指向这个​​FILE结构​​,当它处于活动状态时由流使用。
2.流通过​​fopen函数​​打开。为了打开一个流,我们必须指定需要访问的文件或设备以及他们的访问方式(读、写、或者读写)。Fopen和操作系统验证文件或者设备是否存在并初始化FILE。
3.根据需要对文件进行​​读写操作​​。
4.最后调用​​fclose函数​​关闭流。关闭一个流可以防止与它相关的文件被再次访问,保证任何存储于缓冲区中的数据被正确写入到文件中,并且释放​​FILE结构​​。

标准I/O更为简单,因为它们并不需要打开或者关闭。

I/O函数以三种基本的形式处理数据:单个字符、文本行和二进制数据。

对于每种形式都有一组特定的函数对它们进行处理。

各形式数据的输入/输出函数

家族名

目的

可用于所有流

只用于stdin和stdout

getchar

字符输入

fgetc、getc

getchar

putchar

字符输出

fputc、putc

putchar

gets

文本行输入

fgets

gets

puts

文本行输出

fputs

puts

scanf

格式化输入

fscanf

scanf

printf

格式化输出

fprintf

printf

文件指针

我们知道,文件是由操作系统管理的单元。

当我们想操作一个文件的时候,让操作系统帮我们打开文件,操作系统把我们指定要打开文件的信息保存起来,并且返回给我们一个指针指向文件的信息。文件指针也可以理解为代指打开的文件。这个指针的类型为​​FILE类型​​。该类型定义在​​stdio.h头文件​​中。通过文件指针,我们就可以对文件进行各种操作。

对于每一个ANSI C程序,运行时系统必须提供至少三个流——​​标准输入(stdin)​​、​​标准输出(stdout)​​、​​标准错误(stderr)​​,它们都是一个指向​​FILE结构​​的指针。

标准输入是缺省情况下的输入来源,标准输出时缺省情况下的输出设置。具体缺省值因编译器而异,通常标准输入为键盘设备、标准输出为终端或者屏幕。

下图是三个​​FILE文件​​的指向:

C语言 文件操作相关概念_数据

ANSI C并未规定FILE的成员,不同编译器可能有不同的定义。VS下FILE信息如下:

struct _iobuf { 
char *_ptr; //文件输入的下一个位置
int _cnt; //剩余多少字符未被读取
char *_base; //指基础位置(应该是文件的其始位置)
int _flag; //文件标志
int _file; //文件的有效性验证
int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
int _bufsiz; //文件的大小
char *_tmpfname; //临时文件名
};
typedef struct _iobuf FILE;

文件缓冲区

文件缓冲区概念

ANSI C标准采用“缓冲文件系统”处理数据文件

所谓缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去

如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量) 。

那么文件缓冲区有什么作用呢?

如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。

C语言 文件操作相关概念_开发语言_02