像我们平常被要求做的表格,文档都属于文件。
-
目录
什么是文件
那什么是文件的具体定义呢?
文件是在磁盘上的存储的文件
那么为什么要使用文件呢?
平常我们在学习过程中,当我们编译,运行程序,得出结果之后系统会自动销毁代码使用的内存空间,使用数据,可以是数据持久化,将数据直接存储在计算机的硬盘之中。
文件按照功能可以分为两类,一种是程序文件,另一种是数据文件
程序文件可以分为 源程序文件(.c),目标文件(.h),以及可执行程序(.exe)
数据文件就是程序运行时读写的文件
程序——写(输出)——>文件
内存<——读(输入)—-——文件
是输入还是输出是要根据内存来判断
文件名的定义是唯一的
文件路径+文件名主干+文件名后缀
例如:C:\code\test.exe
文件的打开和关闭
首先我们要先介绍一种指针——文件指针
每一个被使用的文件都在内存中开辟了一个相应的文件信息区来存放文件的相关信息
信息保存在结构体中,该结构体类型由系统声明:FILE* pf(指针名)
pf指向文件信息区,通关文件信息区来找到文件
接下来介绍第一个函数
fopen——打开文件(返回成功则返回FILE*, 返回失败则返回空指针)
关于fopen的打开方式有很多种
“r”:读取(为了输入数据,打开一个已经存在的文本文件) 如果指定文件不存在,则显示出现错误. “w”:写入(为了输出数据,打开一个文本文件) 如果指定文件不存在,则建立一个新文件 “a”:追加(向文本文件尾添加数据) 如果指定文件不存在,则建立一个新文件 “r+”:(为了读和写,打开一个文本文件) 如果指定文件不存在,则显示出现错误. “w+”:(为了读和写,打开一个文本文件) 如果指定文件不存在,则建立一个新文件 “a+”:(打开一个文件,在文件尾进行读写) 如果指定文件不存在,则建立一个新文件 “rb”:只读(为了输入数据,打开一个二进制文件) 如果指定文件不存在,则显示出现错误. “wb”:只写(为了输出数据,打开一个二进制文件) 如果指定文件不存在,则建立一个新文件 “ab”:追加(向二进制文件尾添加数据) 如果指定文件不存在,则建立一个新文件 “rb+”:只读(为了读和写,打开一个二进制文件) 如果指定文件不存在,则显示出现错误. “wb+”:只写(为了读和写,打开一个二进制文件) 如果指定文件不存在,则建立一个新文件 “ab+”:追加(打开一个二进制文件,在文件末尾进行读和写) 如果指定文件不存在,则建立一个新文件 |
fclose——关闭文件
格式:fclose(FILE* pf)
我们要先普及一个流的概念
程序员无法对所有的设备进行完全的掌握,就抽象了一个流的概念,只需要把数据写入流中,不需要对外部设备进行深度的理解
在我们日常生活中就有很多流
终端设备(屏幕) 标准输出流——stdout
键盘 标准输入流——stdin
屏幕 标准错误流——stderr
举得例子是在我们使用的时候默认打开的。
文件顺序读写函数
fputc——字符输入函数 ——所有输入流
int fputs(int character(内容),FILE* pf)
fgetc——字符输出函数——所有输出流
int fputs(FILE* pf)读取后文件指针会指向下一个数据,连续使用可以连续读取
注意:遇到文件末尾和读取错误是不同的两种状态,返回值会有区别,具体下面会讲到
文本行输入输出函数
fputs——所有输入流(写一行数据)
fgets——所有输出流(读一行数据)(把读到的数据拷贝到新的空间中)
格式:char* fgets(char* str ,int num,FILE*pf)
格式化的读写
fprintf(写)(文件指针,写的内容)(写的内容的printf一般无二)
fscanf(读)文件指针,写的内容)(写的内容的scanf一般无二)
sprintf——把格式化的数据写成字符串
int sprintf(char* str,const char*format,可变参数)
sscanf——把字符串数据写成格式化数据
fwrite——二进制写入——文件流
格式:size_t(实际上读到的有效元素的个数)
fwrite(const void*ptr(指向要写的数据(比如结构体指针和数组指针或使用”&“)),
size_t size(单个元素大小),
size_t count(元素的个数),
FILE*stream)
fread——二进制读取——文件流(把流中大小为size*count的数据放入ptr)
格式:size_t
fread( void*ptr(指向要写的数据(比如结构体指针和数组指针或使用”&“)),
size_t size(单个元素大小),
size_t count(元素的个数),
FILE*stream)
文件的随机读写
fseek:根据文件指针的位置和偏移量来定位文件指针
格式:fseek(FILE* stream,long int offset,int origin)
这个origin有三种选择:
1.SEEK_SET——文件的开始
2.SEEK_CUR——文件指针当前位置
3.SEEK_END——文件的末尾
注:向前(向上一级)偏移是“-”;向后(下一级)偏移是“+”;
ftell——返回文件指针相当于起始位置的偏移量
格式:long int ftell (FILE* stream)
rewind——让文件指针返回文件的起始位置
格式:void rewind(FILE*stream)
文本文件和二进制文件
文本文件:以ASCII字符的形式存储的文件(要求在外存(硬盘)上以ASCII形式存储,需要在存储前进行转换)
二进制文件:数据在内存中以二进制的形式存储,不转换的输出到外存
这里就要提及数据在内存的存储方式
字符一律以ASCII形式存储
数值型数据即可以用ASCII码的形式,也能用二进制形式
举个例子:
10000二进制形式:00000000 00000000 00100111 0001000
文本文件(ASCII):1——49(00110001)0——48(00110000)...
二进制文件0000 0000 0000 0000 0010 0111 0001 0000
0 0 0 0 2 7 1 0
在小端模式下就显示出 10 27 00
文件结尾读取结束的判定
我在上面提到过一嘴,fgets和fgetc的判定是有区别的
feof——当文件读取结束的时候,判断读取结束的原因,是否为遇到文件尾结束
牢记一点:在文件读取过程中,不能用feof函数的返回值直接判断文件是否结束
(1)文本文件
文本文件判断是否结束,判断返回值是否为EOF或NULL
fgetc判断是否为EOF;fgets判断是否为NULL
文件读取失败有两个原因:1.遇到文件末尾
2.出错
如果是fgetc函数
1.遇到文件末尾,首先返回EOF,并且标记一个状态,可用feof检测
2.出错,首先返回EOF,并且标记一个状态,可用ferror检测
(2) 二进制文件
判断返回值是否小于实际要读的个数(fread函数)
文件缓冲区(其大小有c的编译系统决定)
ANSIC标准采用缓冲文件系统处理的数据文件
文件缓冲系统——系统自动的在内存中为程序中的每一个正在使用的文件开辟出一块文件缓冲区
主要的过程是从内存向磁盘输出数据回显送到内存中的缓冲区后,才一起送到磁盘上。