一、为什么使用文件
当我们在编写一个项目的时候,自然而然想到要把之前写入的数据保存起来。而只有我们自己选择删除数据的时候,数据才不复存在。这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。此处我们就讲到如何将数据放入到磁盘文件当中。
二、什么是文件
磁盘上的文件是文件。 在程序设计中,文件类型一般分为两种:程序文件和数据文件。
2.1 程序文件
源程序文件(后缀为.c),目标文件(Windows环境中为.obj),可执行程序(windows环境后缀为.exe)。
2.2 数据文件
文件的内容不一定是程序,而是程序运行时写的数据。
2.3 文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。 文件名包含3部分:文件路径+文件名主干+文件后缀 例如: D:\Gitcode\Rookie.c 为了方便起见,文件标识常被称为文件名
三、文件的打开与关闭
3.1 文件指针
缓冲文件系统中,关键的概念是"文件类型指针",简称文件指针。 每一个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置)。这些信息是保存在一个结构体变量当中的。该结构体类型是有系统声明的,取名为FILE.
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
typedef struct _iobuf FILE;
FILE* pf;
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。没当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息。不需要题太在意其中的细节。在创建了FILE结构的变量之后,我们该怎么样来使用和维护它呢。 一般通过一个FILE的指针来维护FILE结构的变量,这样使用起来更加方便。 下面我们创建一个FILE*的指针变量:
FILE* pf
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
3.2 文件的打开与关闭
FILE * fopen ( const char * filename, const char * mode );
int fclose ( FILE * stream );
对于文件的写入和读取方式,重点掌握以下几种即可。
使用实例
#include <stdio.h>
int main ()
{
FILE * pFile;
pFile = fopen ("MYbook.txt","w");
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
fclose (pFile);
}
return 0;
}
四、文件的顺序读写
scanf:按照一定的格式从键盘输入数据 printf:按照一定的格式把数据打印(输出)到屏幕上 fscanf:按照一定的格式从输入流(文件/stdin)输入数据 fprintf:按照一定的格式向输出流(文件/stdin)输出数据
五、文件随机读写
5.1 fseek
根据文件指针的位置和偏移量来定位文件指针。 第一个参数是文件指针的名字(流),第二个参数是文件指针向后偏移数,第三个参数是下图中fseek提供的三个选项之一。 使用实例
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return;
}
fseek(pf, 1, SEEK_SET);
int ch = fgetc(pf);
printf("%c\n", ch);
fseek(pf, 3, SEEK_CUR);
ch = fgetc(pf);
printf("%c\n", ch);
fseek(pf, -5, SEEK_END);
ch = fgetc(pf);
printf("%c\n", ch);
fclose(pf);
pf = NULL;
return 0;
}
在每使用完一次fseek函数后,文件指针会自动向后移动一位。
5.2 ftell
返回文件指针相对于起始位置的偏移量 代码实测
#include <stdio.h>
int main ()
{
FILE * pFile;
long size;
pFile = fopen ("MyRookie.txt","rb");
if (pFile==NULL) perror ("Error opening file");
else
{
fseek (pFile, -5, SEEK_END);
size=ftell (pFile);
fclose (pFile);
printf ("Size of myfile.txt: %ld bytes.\n",size);
}
return 0;
}
5.3 rewind
让文件指针的位置回到文件的起始位置 代码实测:
#include <stdio.h>
int main ()
{
int n;
FILE * pFile;
char buffer [27];
pFile = fopen ("MyRookie.txt","w+");
for ( n='A' ; n<='Z' ; n++)
fputc ( n, pFile);
rewind (pFile);
fread (buffer,1,26,pFile);
fclose (pFile);
buffer[26]='\0';
puts (buffer);
return 0; }
六、文本文件和二进制文件
根据数据的组织形式,数据文件被称为文本文件或者二进制文件。 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文 本文件。 一个数据在内存中是怎么存储的呢? 字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。 如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而 二进制形式输出,则在磁盘上只占4个字节(VS2019测试)。
#include <stdio.h>
int main()
{
int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf);
fclose(pf);
pf = NULL;
return 0; }
此时去文件里查看文本发现变成了不认识的符号 我们在编译器中打开 此时显示为 注:编译器为小端存储的方式显示二进制 今天的讲解就到这里了
|