20211301 学习笔记2
20211301《Unix/Linux系统编程》学习笔记1
教材笔记总结
学习目标
-
本章是复习C语言中的文件操作内容,结构化从文本文件操作,二进制文件操作两个大内容考虑,以前可能只关注文本文件的操作,我们以后更多的是操作二进制文件。
-
文本文件中考虑字符读写,行读写,任意位置读写等
-
文件操作都有什么?
-
二进制文件和文本文件如何转换?
-
数据结构如何读写?
9.1 I/O库函数
- 了解:系统调用是文件操作的基础,他们只支持数据块的读、写
9.2 I/O库函数与系统调用
-
I/O库函数:fopen、fread、fwrite、flseek、fclose
-
系统调用:open、read、write、lseek、close (I/O库函数的根都在对应的系统调用函数中)
-
区别:
-
系统调用中文件描述符fd是一个整数、io中fp是一个文件流指针
-
系统调用用open打开文件读取,并返回一个整数文件描述符fd,若失败返回-1,io库函数fopen返回一个file结构体指针,若失败,返回NULL
-
系统调用使用while循环读取/写入文件,在每个迭代中,发出read系统调用,将最多4kb的字符读入buff[],将各字符写到文件描述符中,较为低效。
-
-
显示文件内容
-
复制文件
-
fopen使用字符串表示模式,返回一个指向file结构体的指针,fopen发出open系统调用打开文件,获取文件描述符fd,分配FILE结构体、内部缓冲区
-
若fopen调用失败程序终止,在失败时返回一个NULL指针,例如 文件不能在指定模式下打开
-
while循环复制文件内容,读取BLKSIZE字节,fread和fwrite一般形式是
-
上面程序尝试一次性读写BLKSIZE字节,size*nitems=BLKSIZE,但是size>1可能会在最后一个fread上出现问题,因为剩余字节可能小于size,为了处理尾部,在while循环后弥漫添加以下代码:
-
fseek与lseek工作原理相同,将R|W指针定位到总字节位置。
-
用fclose关闭文件
-
9.3 IO库函数的算法
-
fread算法:第一次调用read算法,FILE结构体的缓冲区是空的,用保存的文件描述符fd发出一个系统调用,用数据块填充内部的fbuf,然后初始化fbuf的指针、计数器和状态变量。数据复制到缓冲区,满足内部缓冲区的fread调用,若内部缓冲区没有足够数据,则在发出一个read的系统调用来填充
-
fwirite:与fread相反,数据传输方向相反
-
fclose:若文件以写的方式被打开,会先关闭文件流的局部缓冲区,然后发出close(fd)系统调用来关闭FILE结构体中的文件描述符,最后释放结构体,并将指针重置为null
9.4 IO库或系统调用的使用
- fread依赖read将数据从内核被复制到内部缓冲区,然后从内部缓冲区将数据复制到程序缓冲区,传输了两次数据,而read只传输一次
9.5 IO库模式
-
fopen中的模式参数可以指定为:r w a(追加),加+若文件不存在则创造文件
-
字符模式:fgets返回的是整数,返回文件结束符(通常-1),与字符区分开
-
行模式:从fp中读取最多为1行的字符
-
格式化IO:
-
其他函数
-
限制混合:同时读写,规范要求对每个fread和fwrite之间至少有一个fseek或ftell
其他
-
文本文件:如果一个文件说是文本文件,使用任何一种文本编辑器打开可以展现出人类可读信息字符,因为编码都符合某种编码方式,如ASCII、UTF8、GB2312等等(在文件头可以读出来是什么编码方式,然后文本编辑器再按照规则去读取翻译成对应的字符,展示给我们的就是可读的了)
-
二进制文件:如果一个文件说是二进制文件,肯定没有编码方式,使用某些文本编辑器可以打开,展现出来的就是可能一些乱码的字符;也有些可以读取二进制文件的,展示出来就是原始的0101这种二进制了。比如说使用UtralEdit可以显示原始的二进制文件,显示的就是原始16进制。右侧自动选了一种编码方式进行翻译成文本,比如他自动选择的就是GBK,显示出来就是乱码。
-
转换:使用vim修改
vim -b 文件名
:%!xxd ——转化成16进制
——————————————————————
:%!xxd -r——转回去
:wq
代码实现
- 文本文件中考虑字符读写,行读写,任意位置读写
- 读取字符
#include <stdio.h>
int main() {
FILE *file;
char c;
// 打开文件
file = fopen("example.txt", "r");
if (file == NULL) {
printf("无法打开文件。\n");
return 1;
}
// 读取并打印文件中的字符
while ((c = fgetc(file)) != EOF) {
printf("%c", c);
}
// 关闭文件
fclose(file);
return 0;
}
- 会以读写模式打开名为example.txt的文本文件,读取并打印文件中的字符,使用fprintf函数在文件末尾添加了一段新的文本。在使用fopen函数时使用的模式字符串为"r+",表示以读写模式打开文件。
#include <stdio.h>
int main() {
FILE *file;
char c;
// 打开文件以读写模式
file = fopen("example.txt", "a+");
if (file == NULL) {
printf("无法打开文件。\n");
return 1;
}
// 在文件末尾添加一些文本
fprintf(file, "abc");
// 关闭文件
fclose(file);
return 0;
}
- 在任意位置读取文件
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "r"); // 文件名(根据自己的需求修改)
if(file != NULL) {
long int position = 5; // 要读取的位置(根据自己的需求修改)
fseek(file, position, SEEK_SET); // 设置文件指针的位置
int c;
while((c = fgetc(file)) != EOF) {
putchar(c); // 打印字符
}
fclose(file);
} else {
printf("无法打开文件\n");
}
return 0;
}
- 二进制与文本文件间的转换
#include <stdio.h>
void binaryToText(const char* binaryFileName, const char* textFileName) {
FILE* binaryFile = fopen(binaryFileName, "rb");
FILE* textFile = fopen(textFileName, "w");
if (binaryFile != NULL && textFile != NULL) {
int value;
while (fread(&value, sizeof(int), 1, binaryFile) == 1) {
fprintf(textFile, "%d ", value);
}
fclose(binaryFile);
fclose(textFile);
printf("转换成功: 二进制文件 -> 文本文件\n");
} else {
printf("无法打开文件\n");
}
}
void textToBinary(const char* textFileName, const char* binaryFileName) {
FILE* textFile = fopen(textFileName, "r");
FILE* binaryFile = fopen(binaryFileName, "wb");
if (textFile != NULL && binaryFile != NULL) {
int value;
while (fscanf(textFile, "%d", &value) == 1) {
fwrite(&value, sizeof(int), 1, binaryFile);
}
fclose(textFile);
fclose(binaryFile);
printf("转换成功: 文本文件 -> 二进制文件\n");
} else {
printf("无法打开文件\n");
}
}
int main() {
const char* binaryFileName = "binaryfile.bin";
const char* textFileName = "example.txt";
// 二进制文件转换为文本文件
binaryToText(binaryFileName, textFileName);
// 文本文件转换为二进制文件
textToBinary(textFileName, binaryFileName);
return 0;
}
苏格拉底提问
问题与解决方案
-
问题1 :在对文本文件进行写操作时,txt文件没有添加的内容
-
解决方案:在程序运行时关闭文件,等程序运行完再打开文件就可以看到添加的内容了
心得体会
如果电脑上的任何操作都可以使用程序去完成,那么鼠标的重要性就极大地降低了,代码可以解决我们现在使用的大多数问题,只是我们还不太熟悉如何使用,我们更习惯用鼠标,但是作为一个程序员,应该更加懂得用程序解决一切问题,这样不仅提升了效率,还锻炼了编程能力。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架