文件
1、文件的概述
1、文件分类(存储介质)
磁盘文件:文件的数据 存放在磁盘上(音视频、图片文件、文档文件)
设备文件:通过系统将外部设备抽象文件
2、文件分类(存储方式)
任何磁盘文件 在物理上都是二进制存储。
逻辑上:磁盘文件分为二进制文件、文本文件
文本文件:基于字符编码的文件 二进制文件:基于值编码的文件
3、文本文件
基于字符编码,常见编码有 ASCII、UNICODE 等
一般可以使用文本编辑器直接打开
例如:数 5678 的以 ASCII 存储形式为: ASCII 码:00110101 00110110 00110111
00111000 歌词文件(lrc):文本文件
4、二进制码文件:
基于值编码,把内存中的数据原样输出到磁盘上
一般需要自己判断或使用特定软件分析数据格式
例如:数 5678 的存储形式为: 二进制码:00010110 00101110
5、二进制和文件文件的区别
文本文件:
优点:一个字节一个意思、便于查看
缺点:空间大、效率低
二进制文件:
优点:效率高、空间小
缺点:不定长、不便于查看
2、文件缓冲区
文件缓冲区的目的:提高访问效率 提高磁盘使用寿命

1、文件缓冲区的刷新方式
1、行刷新(遇到换行符 刷新)
printf("ssss\n")
while(1)2、满刷新(缓冲区数据放满 刷新)
inti=0;
for(i=0;i<1000;i++){
printf( " 123456789" );
usleep(20*1000 );
}
while (1);3、强制刷新(使用fflush函数 将缓冲刷新)
fflush(stdout)4、关闭耍新 (关闭文件的时候 将缓冲区数据 全部刷新)
#include<unistd.h>2、模拟时钟

3、文件指针
所有操作文件的库函数 都需要借助 文件指针 操作文件。

为每一个进程 默认打开的3个文件指针
stdin:
标准输入默认为当前终端 (键盘)
我们使用的scanf、getchar 函数默认从此终端获得数据
stdout:标准输出默认为当 前终端(屏幕)
我们使用的printf、puts函数默认输出信息到此终端
stderr:标准错误输出设备文件默认为当 前终端(屏幕)
当我们程序出错使用:perror函数时信息打印在此终端4、文件的API
文件的操作步骤:打开 读写 关闭
1、打开文件fopen
1 FILE *fopen(const char *path, const char *mode);
2 path:文件的路径
3 mode:打开文件方式
4 返回值:
5 成功:就是打开的文件指针
6 失败:NULL文件的打开方式mode:
r w a + t b
r:只读的方式打开 w:只写的方式打开 a:追加的方式打开 +:可读可写方式打开
t:以文本文件方式打开 (默认是省略)
b:以二进制方式打开(必须显示说明)
2、关闭文件 fclose
1 int fclose(FILE *fp);
2 返回值:
3 成功返回 0
4 失败返回非 0FILE *fp = NULL;
fclose(fp)3、一次读写一个字符 fputc fgetc
函数的定义:
int fputc(int c, FILE *stream)
函数的说明:
fputc将c的值写到stream所代表的文件中。
返回值: .
如果输出成功,则返回输出的字节值;
如果输出失败,则返回一个EOF。
EOF是在stdio.h文件中定义的符号常量,值为-1
EOF只是在文本文件中有效。FILE *fp = NULL;
fp = fopen("test.txt", "w");
char *file_data = "hello world";
while (*file_data != '\0')
{
fputc(*file_data, fp);
file_data++;
}
fclose(fp);
}函数定义:
int fgetc(FILE *stream);
函数说明:
fgetc从stream所标示的文件中读取-一个字节, 将字节值返回
返回值:
以t的方式:读到文件结尾返回EOF
以b的方式:读到文件结尾,使用feof(后面会讲)判断结尾
4、一次读写一个字符串
写一个字符串
int fputs(const char *s, FILE *stream)读取一个字符串(遇到换行符 结束) ,读取一行文件数据
1 char *fgets(char *s, int size, FILE *stream)
2 成功返回目的数组的首地址,即 s
3 失败返回 NULL1 void test06()
2 {
3 FILE *fp_r = fopen("test.txt", "r");
4 if (fp_r == NULL)
5 {
6 perror("fopen");
7 return;
8 }
9 FILE *fp_w = fopen("b.txt", "w");
10 if (fp_w == NULL)
11 {
12 perror("fopen");
13 return;
14 }
15
16 while (1)
17 {
18 char buf[128] = "";
19 //读一行
20 char *ret = fgets(buf, sizeof(buf), fp_r);
21 if (ret == NULL)
22 break;
23
24 //写一行
25 fputs(buf, fp_w);
26 }
27
28 fclose(fp_r);
29 fclose(fp_w);
30 }5、一次读写n块文件数据 fwrite fread
块写:将内存的数据 原样的写入到 磁盘文件中
1 size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
2 返回值: 实际写入的块数HERO hero[] = {{"德玛西亚", 50, 80}, {"小法", 70, 30}, {"盲僧", 80, 80}};
int n = sizeof(hero) / sizeof(hero[0]);
FILE *fp = fopen("hero.txt", "w");
fwrite(hero, sizeof(HERO), n, fp);快读:将磁盘数据 原样 输入到 内存
1 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
2 返回值:
3 实际读到的整块数:不足一块 不计数 但是数据是读到的HERO hero[3];
memset(hero, 0, sizeof(hero));
FILE *fp = fopen("hero.txt", "r");
fread(hero, sizeof(HERO), 3, fp);6、格式化读写
1、格式化写 fprintf
fprintf (文件指针,格式字符串,输出表列)HERO hero[] = {{"德玛西亚", 50, 80}, {"小法", 70, 30}, {"盲僧", 80, 80}};
int n = sizeof(hero) / sizeof(hero[0]);
FILE *fp = fopen("hero.txt", "w");
//格式化写fprintf
int i = 0;
for (i = 0; i < n; i++)
{
fprintf(fp, "%s %d %d\n", hero[i].name, hero[i].atk, hero[i].def);
}2、格式化读 fscanf
int i = 0;
for (i = 0; i < 3; i++)
{
fscanf(fp, "%s %d %d", hero[i].name, &hero[i].atk, &hero[i].def);
}fprintf fscanf成对使用 效率低 阅读性高
fwrite fread成对使用 效率高 阅读性低
5、文件的随机读写
文件默认是顺序读写:读写才能移动流指针 用户不能修改
随机读写:用户可以更改文件流指针的位置
1 void test05()
2 {
3 FILE *fp = fopen("c.txt", "w+");
4 if (fp == NULL)
5 {
6 perror("fopen");
7 return;
8 }
9
10 //写
11 fputs("hello file", fp);
12 fclose(fp);
13
14 fp = fopen("c.txt", "r");
15 //读
16 char buf[128] = "";
17 fgets(buf, sizeof(buf), fp);
18 printf("读到的数据%s\n", buf);
19
20 fclose(fp);
21 }2、随机读写的API
fseek rewind ftell
1、rewind复位文件流指针
void rewind(FILE *stream);2、ftell返回文件流指针 距离文件首部的 字节数
long ftell(FILE *stream);
3、fseek文件流指针定位
int fseek(FILE *stream, long offset, int whence);1 whence 起始位置
2 文件开头 SEEK_SET 0
3 文件当前位置 SEEK_CUR 1
4 文件末尾 SEEK_END 2
5 offset:流指针的偏移量
6 如果為正数 向右偏移(单位为字节数) 为负数就是向左偏移1 #include <stdlib.h>
2 #include <string.h>
3 void test06()
4 {
5 FILE *fp = fopen("c.txt", "r");
6 if (fp == NULL)
7 {
8 perror("fopen");
9 return;
10 }
11
12 fseek(fp, 0, 2);
13 long len = ftell(fp);
14 //复位文件流指针
15 rewind(fp);
16 printf("文件总大小:len=%ld\n", len);
17
18 unsigned char *text = (unsigned char *)calloc(1, len + 1);
19 fread(text, len, 1, fp);
20
21 printf("%s\n", text);
22 fclose(fp);
23
24 //释放堆区空间(不是必须)
25 if (text != NULL)
26 {
27 free(text);
28 text = NULL;
29 }
30 }6、文件加密器

阿源的知识库