文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。文件标识包括3部分:
(1)文件路径;(2)文件名主干;(3)文件后缀。
文件分类
根据数据的组织形式,数据文件可分为ASCI文件和二进制文件。
数据在内存中是以二进制形式存储的,如果不加转换地输出到外存,就是二进制文件,可以认为它就是存储在内存的数据的映像,所以也称之为映像文件(image file)。
如果要求在外存上以ASCII代码形式存储,则需要在存储前进行转换。ASCI文件又称文本文件(text file),每一个字节放一个字符的ASCII代码。
文件缓冲区
ANSI C标准采用**“缓冲文件系统”**处理数据文件,所谓缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区。从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量),见图10.2。缓冲区的大小由各个具体的C编译系统确定。
刷新缓冲区:
1、缓冲区满了 2、调用函数fflush 3、程序结束
文件指针
概念
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的有关信息(如文件的名字、文件状态及文件当前位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名为FILE。
FILE在stdio.h文件中的类型声明:
typedef struct{
short level;//缓冲区“满”或“空”的程度
unsigned flags;//文件状态标志
char fd;//文件描述符
unsigned char hold;//如缓冲区无内容不读取字符
short bsize;//缓冲区的大小
unsigned charw bufler;//数据缓冲区的位置
unsigned char # curp;//指针当前的指向
unsigned istemp;//临时文件指示器
short token;//用于有效性检查
}FILE;
对文件进行读写等操作的时候,对文件指针进行操作即可。
c语言中由三个特殊的文件指针无需定义,在程序中可以直接使用:
stdin:标准输入,默认为当前终端(键盘)。
stdout: 标准输出,默认为当前终端(屏幕)。
stderr: 标准错误输出设备文件 默认当前终端(屏幕)
定义方式
FILE * 指针变量标识符;
打开文件fopen
函数:FILE *fopn(const char path, const char mode);
打开一个已经存在的文件,并返回文件的文件指针。或者创建一个文件,并打开文件,返回文件标识。
读取成功为文件地址,失败为0
参数:
1、文件的路径
- 绝对路径
- 项目路径
2、 文件打开方式
关闭文件 fclose
函数:int fclose(FILE *fp);
关闭fp所代表的文件。一个文件只能关闭一次。
返回值:
成功返回0,失败返回非0
#include<stdio.h>
#pragma warning(disable:4996)
int main()
{
FILE* file1 = fopen("./test.txt", "r+");
if (file1 == NULL) {
printf("文件打开失败\n");
return 0;
}
printf("打开成功\n");
fclose(file1);
return 0;
}
读写字符函数
EOF:是stdio.h文件中定义的符号常量,值未-1
fgetc
int fgetc(FILE *stream);
返回值:
以文本的方式: 读到文件结尾返回EOF(即-1)
以二进制的方式:读到文件结尾,使用函数feof(文件指针)判断结尾
feof是c语言标准库函数,在stdio.h中,功能是检测刘尚的文件结束符,如果结束返回非0,未结束返回0
fputc
int fpuct(int c, FILE *stream);
将c的值写入sream所代表的文件中。
返回值:
成功返回输出的字节值。
失败返回EOF
int main()
{
FILE* file1 = fopen("./test.txt", "a+");//读写追加方式打开
if (file1 == NULL) {
printf("文件打开失败\n");
return 0;
}
printf("打开成功\n");
char temp;
while ((temp = fgetc(file1)) != EOF) {
printf("%c", temp);
}
fputc('A', file1);//读取完事再写入一个字符A
fclose(file1);
return 0;
}
读写字符串
fgets
char *fgets(char *s, int size, FILE *fp);
从我呢见中读取字符,读取的时候碰到换行符或者文件末尾停止读取,或者读取了size-1个字节的时候停止。
返回值:
成功返回s的地址,失败返回NULL。
fputs
int fputs(const char *str, FILE *fp);
将s指向的字符串,写入到文件中。
返回值:
成功返回写入的字节数,失败返回-1
文件复制:
文件test:
#include<stdio.h>
#pragma warning(disable:4996)
int main()
{
FILE* file1 = fopen("./test.txt", "a+");//
if (file1 == NULL) {
printf("file1文件打开失败\n");
return 0;
}
FILE* file2 = fopen("./test1.txt", "w+");//打开文件test1,没有会新建
if (file2 == NULL) {
printf("file2文件打开失败\n");
return 0;
}
printf("打开成功\n");
char res[100];
//读取字符串,写入文件2
while (fgets(res, 100, file1) != NULL) {
fputs(res, file2);
}
fclose(file1);
fclose(file2);
}
二进制方式读写
fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *fp);
从文件读取数据,一块是size个字节,共nmemb块,存放到ptr指向的内存中。
返回值:实际读到的块数。不到一块,小于size个字节,返回0
fwrite
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *fp);
将ptr指向的内存中的数据,向文件中写入,一块size个字节,共nmemb块。
返回值:实际写入的块数
保存数据,读取数据。
#include<stdio.h>
#pragma warning(disable:4996)
typedef struct stu {
int age;
char name[100];
}STU;
int main()
{
FILE* wFile = fopen("./test.txt", "wb+");
if (wFile == NULL) {
printf("wFile文件打开失败\n");
return 0;
}
STU class[2] = {{11, "Tom"}, {12, "lisi"}};
fwrite(class, sizeof(STU), 2, wFile);//将class数组的数据写入文件
rewind(wFile);//文件指针写操作后,到了最后,需要复位
STU resClass[2];
//循环读取文件数据到resClass数组中。
for (int i = 0; i < 2; ++i) {
fread(&resClass[i], sizeof(resClass[i]), 1, wFile);
}
printf("%d, %s\n", resClass[0].age, resClass[0].name);//11,Tom
printf("%d, %s\n", resClass[1].age, resClass[1].name);//12,lisi
fclose(wFile);
}
随机读写数据
前面介绍的都是顺序读写,从开头到结尾。
我们可以将指针移动到需要读写的位置,再进行读写。这种称为随机读写。
rewind
void rewind(FILE *fp);
把文件内部的位置指针移动到文件开始。
fseek
fseek(FILE *stream, long offset, int origin);
用来改变文件位置标记
参数:
- 文件
- 偏移量
- 起始点
fseek (dp,100L,0);//将文件位置标记向前移到离文件开头100个字节处
fseek (fp,50L,1);//将文件位置标记向前移到离当前位置50个字节处
fseek (fp.-10L,2);//将文件位置标记从文件末尾处向后退10个字节
ftell
long ftell(FILE *fp);
测文件读写位置距为你教案开始由多少个字节。
返回值:
返回读写位置,出错范围-1;
#include<stdio.h>
#pragma warning(disable:4996)
typedef struct stu {
int age;
char name[100];
}STU;
int main()
{
FILE* wFile = fopen("./test.dat", "wb+");
if (wFile == NULL) {
printf("wFile文件打开失败\n");
return 0;
}
STU class[2] = {{11, "Tom"}, {12, "lisi"}};
fwrite(class, sizeof(STU), 2, wFile);
printf("距离%d\n", ftell(wFile));//208
rewind(wFile);
printf("距离%d\n", ftell(wFile));//0
fclose(wFile);
}