欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 12.文件

12.文件

2024/10/25 15:36:51 来源:https://blog.csdn.net/qq_65047384/article/details/139596832  浏览:    关键词:12.文件

知识点一:文件的存取过程

缓冲区的目的:提高存储效率磁盘使用寿命

文件的存取过程

知识点二:磁盘文件分类

物理上所有的磁盘文件都是二进制存储,以字节为单位顺序存储

逻辑上的文件分类:

     文本文件:基于字符编码的文件,如ASCII、UNICODE等,可以文件编辑器直接打开

     二进制文件:基于值编码的文件,数据在内存原样输出到磁盘,需要自己判断或使用特定软件分析数据格式

总结:

    (1)译码:文件文件编码基于字符定长,译码容易些。二进制文件编码变长,译码难一些(不同二进制文件格式,有不同的译码方式)

    (2)空间利用率:二进制文件用一个比特来代表一个意思(位操作)。文本文件任何一个符号需要一个字节

    (3)可读性:文本文件用通用记事本根据几乎可以浏览所有文本文件。二进制文件需要一个具体的文件解码器

知识点三:文件指针

文件指针1
typedef struct
{short level;			//缓冲区“满”或“空”的程度unsigned flags;			//文件状态标志char fd;			//文件描述符unsigned char hold;		//如无缓冲区不读取字符short bsize;			//缓冲区大小unsigned char *buffer;	//数据缓冲区的位置unsigned char *curp;	//指针,当前的指向unsigned istemp;		//临时文件,指示器short token;			//用于有效性检查
}FILE;

注意:不要关心FILE的细节只需要会用FILE定义指针变量就行:FILE *fp=NULL;

C语言有三个特殊的文件指针无需定义,打开直接使用:

(1)stdin:标准输入 默认为当前终端(键盘)

    使用的scanf、getchar函数默认从此终端获得数据

(2)stdout:标准输出 默认为当前终端(屏幕)

    使用的printf、puts函数默认输出信息到此终端

(3)stderr:标准出错 默认当前终端(屏幕)

    当我们程序出错或使用:perror函数时信息打印在此终端

知识点四:打开一个文件

形式:file* fp = null;	//定义一个FILE类型的指针接收返回值fp = fopen(文件名,文件使用方式);
参数:文件名:要打开的文件名字,可以包含路径信息文件使用方式:“读”、“写”、“文本”或“二进制”等
返回值:成功返回相应指针,失败返回NULL

知识点五:文件使用方式

1、r:以只读方式打开文件

    文件不存在:返回NULL

    文件存在:返回文件指针,进行后续读操作

2、w:以只写方式打开文件

    文件不存在:以指定文件名创建此文件

    文件存在:清空文件内容,进行写操作

    若文件打不开(如文件只读),返回NULL

3、a:以追加的方式打开文件(往文件的末尾写入数据)

    文件不存在:以指定文件名创建此文件(同w)

    文件存在,从文件的结尾处进行写操作

4、+:以可读可写的方式打开

5、b:以二进制的方式打开文件

6、t:以文本的方式打开文件(省略)

知识点六:打开方式的组合形式

模式功能
r或rb以只读方式打开一个文本文件(不创建文件)
w或wb以写方式打开文件(使文件长度截断为0字节,创建一个文件)
a或ab以添加方式打开文件,即在末尾添加内容,当文件不存在时,创建文件用于写
r+或rb+以可读、可写的方式打开文件(不创建新文件)
w+或wb+以可读、可写的方式打开文件(使文件长度为0字节,创建一个文件)
a+或ab+以添加方式打开文件,打开文件并在未尾更改文件(如果文件不存在,则创建文件)

知识点七:关闭文件

形式:fclose(文件指针);	//文件指针:指向要关闭的文件
返回值:关闭文件成功,返回值为0关闭文件失败,返回值非零 

知识点八:文件的读写

1、字节读操作

ch = fgetc(fp);		//读一个字节
说明:从指定文件读一个字节赋给ch(以“读”或“读写”方式打开)
文件文件:读到结尾返回EOF
二进制文件:读到文件结尾,使用feof判断结尾

事先本地创建a.text

void test01()
{char buf[127]="";int i = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen("a.txt", "r") ;if(fp == NULL){perror("fopen") ;return ;}//2、对文件的操作while(1){//fgetc调用一次  读取到一个字节 buf[i] = fgetc(fp);if(buf[i] == EOF)//EOF表已经对到文件末尾{break ;}i++;}printf("buf = %s\n",buf);//3、 关闭文件fclose(fp);
}

2、字节写操作

形式:fputc(ch,fp);		//写一个字符
说明:把一个ch变量中的值(1个字节)写到指定文件如果输出成功,则返回输出的字节如果输出失败,则返回一个EOF
注意:EOF是在stdio.h文件中定义的符号常量,值为-1
void test01()
{char buf[127] = "";int i = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen("a.txt", "w") ;if(fp == NULL){perror("fopen") ;return ;}//2、使用fputc进行文件的数据写入printf("请输入要写入文件的字符串:") ;fgets(buf,sizeof(buf),stdin) ;//会获取换行符buf[strlen(buf) - 1] = 0;//去掉键盘输入的换行符//将字符串buf中的元素逐个写入文件中while(buf[i] != '\0'){fputc(buf[i],fp);i++;}//3、 关闭文件fclose(fp);
}

3、字符串写操作

fputs("china",fp);		//写一个字符串
说明:向指定的文件写一个字符串第一个参数可以是字符串常量,字符串数组名或字符指针字符串末尾的'\0'不会写到文件中
void test01()
{char *buf[] = {"床前明月光\n","疑是地上霜\n"};int n = sizeof(buf)/sizeof(buf[0]);int i = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen("a.txt", "w");if(fp == NULL){perror("fopen");return ;}for(i = 0;i<n;i++){fputs(buf[i],fp);} //3、 关闭文件fclose(fp);
}

4、字符串读操作

获取文件一行的数据

形式:fgets(str,n,fp);		//读取一个字符串
说明:从fp指向的文件读入n-1个字符,在读入n-1个字符之前遇到换行符或EOF,读入提前结束,并读取换行符,在最后加一个'\0',str为存放数据的首地址
返回值:成功:返回读到字符串的首元素地址失败:返回NULL
void test01()
{char buf[128] = "";char *path = "a.txt";//int i = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"r");        //fp = fopen("a.txt","r");//fp = fopen("path","r");    //err打开一个文件名叫"path"而不是path指向的文件名"c. txt"if(fp == NULL){perror("fopen");return ;}while(1){char *ret = NULL;         //从文件中读取一行数据 ret = fgets(buf,sizeof(buf),fp);if(ret == NULL)break;printf("%s\n",buf);}    //3、 关闭文件fclose(fp);
}

5、块读写

(1)fwrite数据块写操作

使用 fwrite 将数据块写入到文件中

形式:fwrite(buffer,size,count,fp);
参数说明:buffer:指向存储数据空间的首地址的指针size:一次写的数据块大小count:要写的数据块个数fp:指向要进行写操作的文件指针
返回值:实际写的数据块数(不是总数据大小)
typedef struct
{char name[16];	//姓名int deff;		//防御int atk;		//攻击
}HERO;
void test01()
{HERO hero[] = {{"德玛西亚",80,60},{"盲僧",90,80},{"小法", 40,85},{"小炮",50,90}};char *path = "a.txt";//int i = 0;int n = sizeof(hero)/sizeof(hero[0]);FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"w");if(fp == NULL){perror("fopen");return ;}//fwrite将内存的数据原样的输出到文件中//写入文件的数据不便于用户查看但是不会影响程序的读fwrite(hero,sizeof(HERO),n,fp);    //3、 关闭文件fclose(fp);
}

(2)fread数据块读操作

使用 fread 从文件中读取数据块

形式:fread(buffer,size,count,fp);
参数说明:buffer:指向存储数据空间的首地址的指针size:一次读的数据块大小count:要读的数据块个数fp:指向要进行读操作的文件指针
返回值:实际读的数据块数(不是总数据大小)
typedef struct
{char name[16];	//姓名int deff;		//防御int atk;		//攻击
}HERO;
void test01()
{HERO hero[4]= {""};char *path = "a.txt";int i = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"r");if(fp == NULL){perror("fopen");return ;}fread(hero,sizeof(HERO),4,fp);for(i=0;i<4; i++){//printf(" 英雄姓名:《%s》,防御:%d》, 伤害:《%d》\n",hero[i].name,hero[i].deff,hero[i].atk);printf("英雄姓名:《%s》, 防御:《%d》,伤害:《%d》\n",(hero+i)->name,(hero+i)->deff,(hero+i)->atk);}    //3、 关闭文件fclose(fp);
}

6、格式化读操作

读:fprintf(文件指针,格式字符串,输出列表);
typedef struct
{char name[16];//姓名int deff;//防 御int atk;//攻击
}HERO;
void test01()
{HERO hero[]= {{"德玛西亚",80,60},{"盲僧",90,80},{"小法", 40,85},{"小炮",50,90}};char *path = "a.txt";int i = 0;int n = sizeof(hero)/sizeof(hero[0]);FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"w");if(fp == NULL){perror("fopen");return ;}for(i= 0;i<n;i++){fprintf(fp,"英雄:%s 防御:%d 攻击:%d\n",hero[i].name,hero[i].deff,hero[i].atk);}        //3、 关闭文件fclose(fp);
}

7、格式化写操作

写:fscanf(文件指针,格式字符串,输入列表);
typedef struct
{char name[16];	//姓名int deff;		//防御int atk;		//攻击
}HERO;
void test01()
{HERO hero[4]= {""};char *path = "a.txt";int i = 0;//int n = sizeof(hero)/sizeof(hero[0]);FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"r");if(fp == NULL){perror("fopen");return ;}for(i= 0;i<4;i++){fscanf(fp,"英雄:%s 防御:%d 攻击:%d\n", hero[i].name,&hero[i].deff,&hero[i].atk);}for(i=0; i<4; i ++){printf("%s %d %d\n",hero[i].name,hero[i].deff,hero[i].atk);}//3、 关闭文件fclose(fp);
}

注意:

    (1)用fprintf和fscanf函数对磁盘文件读写使用方便,但在输入时要将ASCII码转换成二进制形式,在输出时将二进制形式转换成字符,花费时间较多

    (2)在内存与磁盘频繁交换数据的情况下,最好不用fprintf和fscanf函数,而用fread和fwrite函数

8、文件随机读写

void test01()
{char buf[128] ="";char *path = "a.txt";int i = 0;//int n = sizeof(hero)/sizeof(hero[0]);FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"w+");if(fp == NULL){perror("fopen");return ;}//先往文件中写入一个字符串"hello file"fputs("hello file",fp);fclose(fp);//重新打开文件让文件的流指针 回到文件首部fp = fopen(path,"r");//在从文件找那个读取该字符串    fgets(buf,sizeof(buf),fp);printf("buf = %s\n",buf);        //3、关闭文件fclose(fp);
}

     如果在写的步骤中没有关闭后再打开文件则会读取到右边等的情况

     所以需要文件写完后需要关闭文件然后重新打开文件,让文件流指针指向文件开始位置让变下次的文件读操作

结果

9、复位文件流指针

形式:rewind(文件指针);
功能;把文件内部的位置指针移到文件开始位置
void test01()
{char buf[128] ="";char *path = "a.txt";FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"w+");if(fp == NULL){perror("fopen");return;}//先往文件中写入一个字符串"hello file"fputs("hello file",fp);//复位文件流指针rewind(fp); //在从文件找那个读取该字符串    fgets(buf,sizeof(buf),fp);printf("buf = %s\n",buf);        //3、 关闭文件fclose(fp);
}

10、获得文件流指针距离文件首部的字节数

形式:ftell(文件指针);
返回值:返回当前位置(距离文件起始位置的字节数),出错返回-1
void test01()
{char buf[128] = "";char *path = "a.txt";long file_len = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"w+");if(fp == NULL){perror("fopen");return;}//先往文件中写入一个字符串"hello file"fputs("hello file",fp);//获取文件流指针距离文件首部的字节数file_len = ftell(fp);printf("file_len = %ld\n",file_len);            //3、关闭文件fclose(fp);
}

11、定位文件的流指针 fseek函数

形式:fseek(文件类型指针,位移量,起始点);	//一般用于二进制文件
功能:移动文件中位置指针的位置
参数说明:位移量:相对 起始点 的偏移量,向前、向后移动的字节数(-10往左边移动10字节,+10往右边移动10字节)起始点:开始添加偏移 位移量 的位置位置指针的位置说明:在文件开头:0		(SEEK_SET)在文件当前位置:1	(SEEK_CUR)在文件末尾:2		(SEEK_END)

一次性读取文件总数

void test01()
{char *file_data = NULL;long file_len = 0;char *path = "a.txt";FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"r");if(fp == NULL){perror("fopen");return ;}//需求:一次性的将文件数据读取到内存中//1、得到文件的总大小//a、 使用 fseek 将文件指针定位到文件尾部fseek(fp,0,2);//b、使用 ftell 计算文件的偏移量==文件的总大小file_len = ftell(fp);//c、使用rewind复位文件流指针rewind(fp);//2、根据文件的总大小合理申请内存空间file_data = (char *)calloc(1,file_len+1);    //+1的目的 内存末尾存放'\0' if(file_data == NULL){fclose(fp);return;}//3、一次性将文件数据读入到内存空间fread(file_data,file_len,1,fp);//4、遍历读取到的文件内容printf("file_len = %ld\n",file_len);printf("%s\n",file_data);//5、释放堆区空间if(file_len != NULL){free(file_len);file_len = NULL;}    // 关闭文件fclose(fp);
}

知识点九:feof()函数判断文件是否到达文件末尾

EOF宏:只能用于文本文文件

feof函数:可以用于文本文文件 二进制文件

判断文件是否结束:0:未结束,非0:表示结束

void test01()
{    char *path = "a.txt";int i = 0;FILE *fp = NULL;//1、 使用fopen打开一个文件获得文件指针fp = fopen(path,"r");if(fp == NULL){perror("fopen");return ;}//feof(fp)判断文件是否结束 0:未结束,非 0:表示结束//while(feof(fp) == 0)//文件未结束才循环while( !feof(fp)){char ch = fgetc(fp);printf("%c",ch);}// 关闭文件fclose(fp);
}

知识点十:文件加密器

加密过程:

加密过程

解密过程:

解密过程

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com