1.文本文件
在文本文件中,数据是以字符形式呈现的,每个字符占用一个字节,而字节在计算机中是以ASCII码来识别;在村村文本时候需要先将ASCII码值来转换为二进制的形式来存储;
如在内存中将整数123以文本形式来存放,如图
‘1’(49) | ‘2’(50) | ‘3’(51) |
00110001 | 00110010 | 00101110 |
由于文本形式存储的是以字符形式展示的,索引整数123被拆分为’1’,’2’,’3’。这三个字符所对应的ASCII码值分别是49,50,51,长方形内的数字是该ASCII码对应的二进制树,每一个二进制数代表一个字节;
2.二进制文件
二进制文件在存储数据时候是直接以二进制方式存储的,这种存储方式与数据在内存中的存储方式相同,不需要转换,因此可以提高存储效率,还能节省存储空间。
如在内存中将整数123以二进制存储
| |
00000000 | 01111011 |
整数123直接以二进制数“00000000 01111011”直接存储的,所以将二进制文件从硬盘中读取到内存中不需要数据转换。
流
流是一个动态的概念,可以将一个字节形象地比喻成一滴水,字节在设备、文件和程序之间的传输的就是流,类似于水在管道中传输;流是对输入输出源的一种抽象,也是对传输信息的一种抽象。通过对输入输出源的抽象,屏蔽了设备之间的差异,使得程序员能以一种通用的方式进行存储操作,通过对传输信息的抽象,使得所有信息都在转化为字节流的形式传输,使得信息解读的过程与传输过程分离;
C语言中,I/O操作可简单看做是从程序移进来或者移出字节,这种搬运的过程称之为流(stream).程序只关心是否正确的输出了字节数据,以及是否正确的输入了要读取的字节数据。i/o细节对程序员是隐藏的。
主要用于设备文件和程序之间的通信;
设备文件如声卡、显卡、键盘等,都通过流来读写。
3.文件缓存系统
- 缓冲文件系统:高级文件系统,系统自动为正在使用的文件开辟缓冲区
- 非缓冲文件系统:低级文件系统,由用户在程序中为每个文件设定缓冲区
4.文件读写
文件类型指针;
FILE *fp;
用法:文件打开时候,系统会自动建立文件结构体,并把指向它的指针返回来,程序通过这个指针获得文件新,访问文件;
文件关闭后,它的文件结构体被释放
Windows为例:
写入的时候文本会将换行符10\n,ASCII码解析为回车符13\r,换行符10\n
读取的时候会将回车符\r13,换行符\n10解析为换行符\n
二进制原样写入写出
在Linux下文本文件与二进制文件读写无差别(Linux)
文件型结构体
C语言中定义的文件型结构体来标识记录待操作的文件的信息,该结构体定义于头文件stdio.h中
struct _iobuf {
char *_ptr; //当前缓冲区内容指针
int _cnt; //缓冲区还有多少个字符
char *_base;//缓冲区起始地址
int _flag;//文件流的状态,是否错误或者结束
int _file;//文件描述符
int _charbuf;//双字节缓冲,缓冲2字节
int _bufsiz;//缓冲区大小
char *_tmpfname;//临时文件名
};
typedef struct _iobuf FILE;
文件打开方式
r | 打开只读文件,该文件必须存在 |
w | 打开只写文件,若文件存在则文件长度清为0,即清空内容,若文件不存在则创建该文件 |
r+ | 打开可读写的文件,文件必须存在 |
w+ | 打开可读写的文件,存在则清空内容,不存在则创建 |
w与w+ | w打开的文件不可以读取 |
rb | 只读打开一个二进制文件,只允许写入数据,文件必须存在 |
wb | 只写打开或者新建一个二进制文件,只允许写入数据 |
rb+ | 读写打开一个二进制文件,只允许读写数据,文件必须存在 |
wb+ | 读写打开或者新建一个二进制文件,允许读写数据 |
rt | 打开只读文件文件,该文本文件必须存在 |
wt | 打开只写文本文件,若存在则清空内容,不存在则创建 |
rt+ | 读写打开一个文件文件,允许读写数据,文件必须存在 |
wt+ | 读写打开或者新建一个二进制文件,允许读写数据 |
a | 以附加方式打开只写文件。文件不存在则创建,存在则在原文件后追加内容 |
a | 以附加方式打开可读写文件。文件不存在则创建,存在则在原文件后追加内容 |
ab | 二进制数据的追加,不存在则创建 |
at | 文本数据的追加,不存在则创建 |
at+ | 读写打开文本文件,允许读或在文本末尾追加数据 |
ab | 读写打开二进制数据文件,允许读或在文本末尾追加数据 |
access函数
Windows
windows下所有文件夹都是可以读写的;
io.h头文件中
_access(“C:\Users\lc\Desktop\1.txt”, 0) ; //0判断文件/文件夹是否存在,返回值-1(不存在)/0(存在)
_access(“C:\Users\lc\Desktop\1.txt”, 2) ; //0判断文件/文件夹是否可写,返回值-1(不可写,不存在肯定不可写)/0(可写)
_access(“C:\Users\lc\Desktop\1.txt”,4) ; //4判断文件/文件夹是否可读,返回值-1(不可读,不存在肯定是不可读的)/0(可读)
_access(“C:\Users\lc\Desktop\1.txt”, 6) ; //0判断文件/文件夹是否可读写,返回值-1(不可读写,不存在肯定不可读写)/0(可写)
Linux
Linux下unistd.h头文件中;
R_OK读权限;
W_OK写权限;
X_OK读写权限;
F_OK文件是否存在;
关闭文件指针
fclose(pf)
作用:使得文件指针变量与文件脱钩,释放文件结构体与文件指针;
正常关闭为0,非0则非正常关闭;
不关闭文件可能会丢失数据;
fread/fwrite
void main() {
int num[100];
for (int i = 0; i < 100; i++) {
num[i] = i;//初始化数组
}
FILE *pf;
pf = fopen("C:\\Users\\lc\\Desktop\\1.txt", "wb+");
if (pf == NULL) {
printf("文件打开失败");
}
else {
int res = 0;
res=fwrite(num, sizeof(int), 100, pf);//将内存写入文件
//写成功多少个,会返回数量
//内存的首地址,从哪里开始写
//一个元素有多大
//写多少个元素
//写到哪个文件,文件指针;
if (res == 100) {
printf("写入成功");
}
else {
printf("写入失败");
}
fclose(pf);
}
}
struct nanzu {
char first[100];
char second[200];
char three[50];
}info[10] = {
{"试问中国男足几多愁","恰似一群太监上青楼","无人能射"},
{ "试问中国男足几多愁","恰似一群太监上青楼","总是被射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","欲罢不射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","尚不能射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","往哪里射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","看比人射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","拿什么射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","尚鞥蛇射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","久久不射" },
{ "试问中国男足几多愁","恰似一群太监上青楼","不再像射" },
};
void main() {
struct nanzu china[10];
FILE *pf = fopen("C:\\Users\\lc\\Desktop\\1.txt", "rb");
if (pf == NULL) {
printf("文件打开失败");
}
else {
int res = 0;
res = fread(china, sizeof(struct nanzu), 10, pf);
//将文件读入内存
//读成功多少个,会返回元素数量
//@parameter1:内存的首地址,从哪里开始写
//@parameter2:一个元素有多大
//@parameter3:读入多少个元素数量
//@parameter4:写到哪个文件,文件指针
if (res == 10) {
printf("读取成功");
struct nanzu *p;
p = &china;
for (int j = 0; j< 10; j++) {
printf("\n%s\t%s\t%s\n", (p + j)->first, (p + j)->second, (p + j)->three);
}
}
else {
printf("读取失败");
}
fclose(pf);
}
system("pause");
}