详解 C 语言文件操作(上)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
一、什么是文件
1.1 - 文件的基本概念
所谓"文件"一般是指存储在外部介质如磁盘上数据的集合。
操作系统是以文件为单位对数据进行管理的也就是说如果想找存在外部介质上的数据必须先按文件名找到指定的文件然后再从该文件中读取数据如果想向外部介质上存储数据也必须先建立一个文件以文件名标识才能向它输出数据。
1.2 - 文件的分类
从不同的角度可对文件作不同的分类。
从用户的角度看文件可分为普通文件和设备文件两种。
-
普通文件是指存储在磁盘或其他外部介质上的一个有序数据集可以是源程序文件后缀为
.c
、目标文件windows 环境后缀为.obj
、可执行文件windows 环境后缀为.exe
也可以是一组待输入处理的原始数据或者是一组输出的结果。源程序文件、目标文件、可执行文件可以称作程序文件输入输出数据可以称作数据文件。 -
设备文件是指与主机相连各种输入输出设备如显示器、打印机、键盘等。在操作系统中把外部设备也看作一个文件来进行管理把它们的输入、输出等同于对磁盘文件的读和写。通常把显示器定义为标准输出文件
stdout
和标准错误文件stderr
把键盘指定为标准输入文件stdin
。ANSI C 标准规定在执行程序时系统先自动打开这三个文件。
从文件编码的方式来看文件可分为 ASCII 码文件和二进制码文件两种。
-
ASCII 文件也称为文本文件这种文件在磁盘中存放时每个字符对应一个字节用于存放对应的 ASCII 码。例如整数 10000 的存储形式为
00110001 0011000 0011000 0011000 0011000
共占用 5 个字节。ASCII 码文件可在屏幕上按字符显示例如源程序文件就是 ASCII 文件。由于是按字符显示因此能读懂文件内容。
-
二进制文件是按二进制的编码方式来存放文件的。例如整数 1000 的存储形式为
00000000 00000000 00100111 00010000
共占用 4 个字节。二进制文件虽然也可以在屏幕上显示但其内容无法读懂。
1.3 - 文件名
一个文件需要有唯一的文件标识即文件名以便用户识别和引用。
文件名包含 3 个部分
-
文件路径
-
绝对路径也称为完整路径是指向文件系统中某个固定位置的路径不会因当前的工作目录而产生变化。为了做到这点它必须包含根目录。
在计算机的文件系统中根目录指文件系统的最上一级目录它是相对子目录来说的它如同一棵大树的"根"一般所有的树杈都以它为起点故被命名为根目录。
以微软公司开发的 Windows 操作系统为例打开这台电脑我的电脑、计算机双击 C 盘就进入 C 盘的根目录双击 D 盘就进入 D 盘的根目录。
Unix 完全抽象了树层次结构的本质在 Unix 和类 Unix 系统中根目录用
/
符号表示。虽然根目录通常称为/
但目录条目本身没有名称它的名称是初始目录分隔符/之前的"空"部分。所有文件系统条目包括已挂载的文件系统都是此根的"分支"。 -
相对路径则是以指定的工作目录作为基点避开提供完整的绝对路径。文件名称就可以被视为以指定工作目录为基点的一个相对路径虽然一般不将其称之为路径。
路径中的 "./" 代表目前所在的目录"../" 代表上一级所在的目录"../../" 则代表上上级所在的目录。
-
-
文件名主干。
-
文件后缀
文件后缀名也叫文件扩展名后缀名可以用来帮助用户了解文件是应该使用哪种软件打开文件。
二、缓冲文件系统和非缓冲文件系统
C 语言所使用的磁盘文件系统有两大类一类称为缓冲文件系统又称为标准文件系统另一类称为非缓冲文件系统。
-
缓冲文件系统的特点
系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区从磁盘向内存读入数据时则一次从磁盘文件将一些数据输入到内存缓冲区充满缓冲区然后再从缓冲区逐个地将数据送给接受变量向磁盘文件输出数据时先将数据送到内存中的缓冲区装满缓冲区后才一起送到磁盘去。
用缓冲区可以一次读入一批数据或输出一批数据而不是执行一次输入或输出函数就去访问一次磁盘这样做的目的是减少对磁盘的实际读写次数因为每一次读写都要移动磁头并寻找磁道扇区。缓冲区的大小由各个具体的 C 版本确定一般为 512 byte即 0.5 kb。
-
非缓冲文件系统的特点
非缓冲文件系统不由系统自动设置缓冲区而由用户自己根据需要设置。在传统的 Unix 系统下用缓冲文件系统来处理文本文件用非缓冲系统处理二进制文件。
1983 年 ANSI C 标准决定不采用非缓冲文件系统而只采用缓冲文件系统。即用缓冲文件系统处理文本文件也用它来处理二进制文件也就是将缓冲文件系统扩充为可以处理二进制文件。
三、文件指针类型
缓冲文件系统中关键的概念是"文件指针类型"简称"文件指针"。
每个被使用的文件都在内存中开辟了一个相应的文件信息区用来存放文件的相关信息如文件的名字、文件状态以及文件当前的位置等。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的取名为 FILE。
例如VS 2013 编译环境提供的 stdio.h
头文件中有以下的文件类型声明
struct _iobuf
{
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
不同的 C 编译器的 FILE 类型包含的内容不完全相同但是大同小异。每当打开一个文件的时候系统会根据文件的情况自动创建 FILE 结构体的变量并填充其中的信息使用者不必关心细节。
一般通过一个 FILE 类型的指针来维护 FILE 结构体的变量这样使用起来更加方便例如
FILE *fp;
四、文件的打开和关闭
文件在读写之前应该先打开文件在使用结束之后应该关闭文件。
ANSIC 规定使用
fopen
函数来打开文件fclose
函数来关闭文件。
4.1 - fopen
FILE* fopen(const char* filename, const char* mode);
参数
-
filename要打开的文件的文件名。
-
mode打开文件的方式。
文件打开方式 含义 "r" read打开文件进行输入操作input operations该文件必须存在 "w" write为输出操作output operations创建一个空文件如果已存在同名文件则会丢弃其内容并将该文件视为新的空文件 "a" append打开文件在文件末尾进行输出操作output operations输出操作始终将数据写入write文件末尾对其进行扩展。重新定位操作repositioning operation fseek
、fsetpos
、rewind
将被忽略。如果文件不存在则创建一个新文件"r+" read/ update打开文件进行输入输出操作该文件必须存在 "w+" write/ update为输入输出操作创建一个空文件如果已存在同名文件则会丢弃其内容并将该文件视为新的空文件 "a+" append/ update打开一个文件进行输入输出操作所有输出操作都在文件末尾写入数据。重新定位操作 fseek
、fsetpos
、rewind
会影响下一个输入操作但输出操作会将位置移回文件末尾。如果文件不存在则创建该文件。使用上面的打开方式文件将作为文本文件打开。
为了将文件作为二进制文件打开mode 中必须包含 b 字符。这个额外的 b 字符要么追加到末尾从而形成复合的 mode"rb"、"wb"、"ab"、"r+b"、"w+b"、"a+b"要么插入到字母和 + 号之间形成混合的 mode"rb+"、"wb+"、"ab+"。
返回值
如果文件打开成功fopen
函数将返回一个 FILE 类型的指针如果打开失败则返回一个 NULL 指针因此需要对 fopen
函数的返回值做检查。
4.2 - fclose
int fclose(FILE* stream);
如果流stream成功关闭则返回 0失败则返回 EOF
。
例如
#include <stdio.h>
int main()
{
FILE* fp = fopen("./test.txt", "r");
if (NULL == fp)
{
perror("fopen");
return 1;
}
fclose(fp);
fp = NULL;
return 0;
}
如果当前目录下并不存在 test.txt 文件文件打开失败终端上将会显示 "fopen: No such file or directory"。