Day16 内容梳理:
C语言学习笔记 Day14(文件管理--上)-CSDN博客
C语言学习笔记 Day15(文件管理--中)-CSDN博客
目录
Chapter 10 文件操作
10.5 文件状态
10.6 文件的随机读写 fseek()、rewind()
(1)fseek():移动光标并开始读写
(2)rewind():将光标重置回文件开头
10.7 文件的删除remove()、重命名rename()
(1)删除remove():
(2)重命名、移动位置rename():
10.8 文件缓冲区
(1)基础概念
(2)更新缓冲区
Chapter 10 文件操作
10.5 文件状态
获取文件的大小
#include<sys/types.h>
#include<sys/stat.h>
int main() {
//文件状态结构体变量
struct stat st;
stat("D:/abc.txt", &st);
printf("文件大小:%d\n", st.st_size);
return 0;
}
10.6 文件的随机读写 fseek()、rewind()
(1)fseek():移动光标并开始读写
之前的文件都是顺序读写,而在可以在随机读写中,改变文件光标的位置。
先创建好一个名为“随机读写.txt”的文本文件,写入如下内容:
fseek()函数的三个参数:文件指针、offset位移数、whence移动的起始位置
offset:往左偏移是负数,往右偏移是正数
whence有三种类型的参数:
SEEK_SET:从文件开头移动offset个字节
SEEK_CUR:从当前位置移动offset个字节
SEEK_END:从文件末尾移动offset个字节
因为文本文件中,每一行的结尾是\r\n(不会显示在文本中),算两个字节,所以算offset的时候需要加上这2个字节。
\r\n存在于除了末尾那行以外的其他行,所以从末尾开始偏移的话不需要考虑\r\n的字节。
代码如下,把三种类型的whence参数都试写了一遍:
int main() {
FILE* fp = fopen("D:/随机读写.txt", "r");
if (!fp) return -1; //处理文件读取失败的情况
char arr[100];
//打印第1行的内容
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
//打印第2行的内容
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
//这行打印完之后,就读完了“12345678”和“abcde”,文件的光标此时移动到了第三行开头
//文件随机读写:从当前位置偏移
//(效果:再打印一遍第2行)
fseek(fp,-7, SEEK_CUR); //格式:文件指针、偏移量、位置。 “abcde”的末尾还有\r\n,各1字节、每个字母1字节,又是往前打印,所以偏移量是-7
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
//文件随机读写:从文件开头偏移
//(效果:再打印一遍第1行)
fseek(fp, 0, SEEK_SET); //格式:文件指针、偏移量、位置。 “12345678”是文件开头,SEEK_SET是从开头开始打印,所以偏移量是0
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
//文件随机读写:从文件末尾偏移
//(效果:打印一遍最后一行)
fseek(fp, -10, SEEK_END); //格式:文件指针、偏移量、位置。 “fghijklmno”的末尾没有\r\n,偏移量是-10,保证能从文件末尾移动到“f”然后往后打印
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
return 0;
}
上图代码的打印结果如下:正常打印了两行,跳到上一行打印了一下,跳到文件开头行打印了一下,又跳到文件末尾行打印了一下
(2)rewind():将光标重置回文件开头
使用方式:rewind(文件指针)
作用效果等同于fseek(文件指针,0,SEEK_SET)
int main() {
FILE* fp = fopen("D:/随机读写.txt", "r");
if (!fp) return -1; //处理文件读取失败的情况
char arr[100];
//打印第1行的内容
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
//打印第2行的内容
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr);
//这行打印完之后,就读完了“12345678”和“abcde”,文件的光标此时移动到了第三行开头
//用rewind(fp)重置光标
rewind(fp);
memset(arr, 0, 100);
fgets(arr, 100, fp);
printf("%s", arr); //会打印第1行的内容,也就是“12345678”
return 0;
}
10.7 文件的删除remove()、重命名rename()
(1)删除remove():
需要注意的是,以这样的方式删除的文件不会进入到回收站中,难以找回,慎用remove()。
删除这个文件:
代码如下:
int main() {
int value = remove("D:/abc.txt");
if (value == 0) printf("删除成功");
else printf("删除失败");
return 0;
}
运行结果:
文件中也确实没有abc.txt了:
(2)重命名、移动位置rename():
①重命名:
把“解密1.txt”更名为”解密加密的原始语句.txt”
代码和效果如下:
int main() {
//重命名rename()
int value = rename("D:/解密1.txt", "D:/解密加密的原始语句.txt"); //两个参数:旧名字、新名字
if (value == 0) printf("改名成功");
else printf("改名失败");
return 0;
}
里面的文本没有发生变动,只有文件名被改了。
②移动位置:
把D盘的“加密1.txt”移动至D盘的“Program Files”文件夹中
int main() {
//移动文件rename()
int value = rename("D:/加密1.txt", "D:/Program Files/加密1.txt"); //两个参数:旧位置、新位置
if (value == 0) printf("移动成功");
else printf("移动失败");
return 0;
}
移动效果:
10.8 文件缓冲区
(1)基础概念
通常用“缓冲文件系统”来处理数据文件。
缓冲文件系统是指系统自动在内存区为程序中每个在使用的文件开辟一个文件缓冲区,暂存从内存向磁盘运输的文件,装满整个缓冲区后才一起送到磁盘中。就像是定时定点到站的公交车一样。
缓冲区的作用是协调低速的输入输出设备和高速的CPU,避免低速的输入输出设备占用CPU,从而解放出CPU并使其能够高效率工作。
缓冲区有两种保存方式,一种是按固定时间间隔保存数据(比如每10秒保存一下),另一种是按固定数据量保存数据(比如每100字保存一下)。
(2)更新缓冲区
不太建议实际写代码时按下图中这样写,因为频繁和硬盘交互会损伤硬盘。最好是手动规定一个字节长度,代码到这个长度了再保存。
int main() {
FILE* fp = fopen("D:/更新缓冲区文件.txt", "w+");
if (!fp) return -1;
char ch;
while (1) {
scanf("%c", &ch);
if (ch == '@') break; //设定个终止输入的符号
fflush(fp); //更新缓冲区
fputc(ch, fp);
}
fclose(fp);
return 0;
}
一边输入,一边保存到了文本文件中: