文件理论内容:
什么是文件:
文件指存储在外部介质上的数据的集合。
文件的使用:
(1)文件是一种保存数据的形式,存放在外部介质上的
(2)操作系统是以文件为单位对数据进行管理
(3)想找存放在外部介质上的数据,先按文件名找到所指定的文件,然后再对文件读数据
(4)要向外部介质上存储数据,也必须先建立一个文件(以文件名作为标志)
流:
流是输入输出的数据传送的过程,数据如流水一样从一处流到另一处,因此常将输入输出形象地称为流(stream),即数据流。流表示了信息从源到目的端的流动。终端键盘是输入文件,显示屏和打印机是输出文件。
输入流:数据从文件(外存)流向计算机内存
输出流:数据从计算机内存流向文件(外存),再将数据输出到.txt或者屏幕上
进程:正在运行的程序
文件的内容:
文件名:文件要有一个唯一的文件表示,以便用户识别和引用。
文件表示包括三部分:
用该路径下a文件举例D:1/2/a.txt
(1)文件路径D:1/2/
(2)文件名主干a
(3)文件后缀 .txt
文件分类:
根据文件中数据的组织形式不同,将文件分为:文本文件和二进制文件。
二进制文件:把数据对应的二进制形式存储到文件中,是字节序列文件。将内存中的数据原封不动挪过来,因为内存中存的是二进制,所以称为二进制文件
文本文件:把要存的数据当作一系列字符组成,把每个字符的ASCII码值存入文件中。每个ASCII码值占一个字节,每个字节表示一个字符,以字符形式将数据存储为 ‘1’‘0’。故文本文件也称作字符文件或ASCII文件,是字符序列文件。
eg:
出现乱码的原因:
编码和解码不是同一个标准。
如果要求在外存上以ASCII代码形式存储,则需要在存储前进行转换为ASCII形式。
字符一律ASCII形式存储,数值型数据既可以ASCII形式存储也可以二进制形式。
多媒体文件包括图片文件,二进制文件包括视频文件等。
文件缓冲区:
因为直接访问磁盘数据的效率很低,所以内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘。缓冲区能够提高两者之间的交互效率。
例如:QQ想要成功登录,必须要在数据库中找到数据与输入的账号和密码匹配,但是数据库在外存中,每次都访问很麻烦,而缓冲区是内存中分配的区域,将经常输入的账户和密码存储在缓冲区中就很大程度提高访问效率。
从内存向磁盘输出数据:装满后缓冲区后将数据放入到磁盘中 ,并不是内存和磁盘直接交互,而是通过缓冲区。(下图中绿色箭头)
刷新缓冲区的方式:\n fflush。
从磁盘像计算机读入数据:磁盘将数据交互到缓冲区,充满\刷新缓冲区将数据输入至程序数据区中。(下图中黄色箭头)
文件的使用:
头文件:#include<stdlib.h>
路径:
相对路径
绝对路径
在字符串中,‘\’有转义字符的含义,例如想要打印”,printf(“ ” ”);没办法打印,需要printf(“ \” ”); 所以,路径的表示用“/”或者“\\ ”
模式决定了如何读文件:
(1) r->只读,前提文件必须存在,不存在会报错
w->只写,文件可以不存在,如果存在则删除原文件,打开空文件;文件不存在,创建文件。
(2) r+ ->可读可写,前提文件必须存在,不存在会报错
w+ ->可读可写,文件可以不存在,如果存在删除原文件,打开空文件。文件不存在,创建。
a+ ->追加方式,可读可写,如果不存在会创建,存在不清楚原内容,会追加内容就是在原有内容后面续上内容。
(3)如果操作的是二进制文件,则应该在r或者w后面加一个’b’。’rb’,’wb’
打开文件fopen操作:
系统参数:文件指针FILE*,FileName是要打开文件的名字,以Mode模式打开
eg: 以写的形式打开”1.txt"文件
FILE* fp = fopen("1.txt","r");
通常将fopen函数的返回值赋给一个指向文件的指针变量。如:
FILE* fp
fp= fopen("1.txt","r");//fp与文件a1.txt相联系,fp指向了a1.txt文件
打开文件fclose操作:
关闭文件,释放资源
使用:fclose(pf);
写文件fwrite操作:
系统参数:文件返回类型size_t返回写入的个数。
fwrite(把写的东西放到buffer内,每个元素的大小,有多少个元素,文件指针-往那个文件里面写);
eg:创建可读可写fp文件命名为aaa,把哈哈哈写到fp文件内:
int main(){
FILE* fp = fopen("aaa.txt","w+");
if (fp == NULL) {
printf("打开失败\n");
}
char buffer[] = "哈哈哈";//把内容存到buffer数组内
int size = fwrite(buffer, sizeof(char), strlen(buffer), fp);//size保存文件返回的内容即书写内容的个数
printf("% d", size);
fclose(fp);
return 0;
}
写文件fread操作:
系统参数:文件返回类型size_t返回读取成功的元素个数。
fread(把数据读到到buffer内保存起来,每个元素的大小,读多少个元素,文件指针-往那个文件里面写);
eg:读取文件fp并输出读取内容。
int main(){
char buffer[20];
int main()
memset(buffer, '\0',20);//'\0'来初始化buffer的长度
while (fread(buffer, sizeof(char), 5, fp) > 0){
printf("%s\n", buffer);
memset(buffer, '\0',20);//清空内存再初始化
}
}
定位文件fseek操作:
想要定位文件,就比如想在文件后面加上一些数据:方式一:以“a”的方式打开;方式二:进行文件定位操作。
fseek的系统参数:文件返回类型int_crdecl,一般不需要该返回值。
fseek(定位的是哪个文件-把文件指针给上去,要偏移的字符个数(假如要在第3个字符后面插入数据就要偏移3个字符),相对位置);
相对偏移量:
>0 向右偏移
<0 向左偏移
相对位置:
seek_cur 当前
seek_end 末尾
seek_set 起始
插入的内容是覆盖原来值:
eg:在123456789的内容中从头数第3个位置插入000
fseek(fp,3,seek_set);
char buffer[]="000";
fwrite(buffer,sizeof(char),3,fp);
结果为:123000789
统计文件大小ftell操作:
使用:long res=ftell(fp);
练习:
文件的拷贝:
#include<stdlib.h>
#include<assert.h>
#include<iostream>
#define _CRT_SECURE_NO_WARNINGS //VS编译器下需要的头文件
//文件的拷贝,将a文件拷贝到b文件中
//就是读取A文件,将读取的内容写到B中,边读边写,最后关闭俩文件
int main()
{
FILE* fp1 = fopen("a", "r+");
/* if (fp1 == NULL)
{
printf("打开文件失败");
return;
}*/
FILE* fp2 = fopen("b", "w+");
assert(fp1 != NULL && fp2 != NULL);
char buffer[128] = { 0 };//数组初始化
int count = 0;
while (count=fread(buffer, sizeof(char), 128, fp1)>0)//1次读取128个字符,当没有内容了就会返回0
{
fwrite(buffer, sizeof(char), count,fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}