(补充)关于文件的读写与判断

5. 文件的随机读写

关于文件的顺序读入,我们逐次使用fgetc函数时它可以依次读入我们文件中的数据;

不能指定读写某个位置的数据内容;

要想实现读入想要的数据内容:可以使用fseek函数实现它可以将文件指针指向我们想要的位置上

5.1 fseek函数

参数1:文件流的起始位置也就是文件信息区域的起始地址;

参数2:相较于origin的偏移量;右边为正偏移;左边为负偏移;

参数3:起始偏移位置;

SEEK_SET:起始偏移位置在文件信息区的开头;

SEEK_CUR:起始偏移位置在上次读入的位置;

SEEK_END:起始偏移位置在文件信息区的末尾;

注意:SEEK_END指向的不是\0;在文件中没有\0的概念;

fseek函数的使用

5.2 ftell函数

偏移量查看函数

返回文件指针相对于起始位置的偏移量

long int ftell ( FILE * stream );

只要给函数一个流就可以知道当前文件指针相较于起始位置的偏移量;

5.3 rewind函数

让文件指针的位置回到文件的起始位置

void rewind ( FILE* stream );

对于文件的学习要记住三步骤;

以什么打开方式打开文件就只能进行怎样的操作;

需要熟悉掌握与各种打开方式相关的功能函数;包括:函数的返回值,函数的参数,函数的使用场景

6.文本文件和二进制文件

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。

数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

一个数据在内存中是怎么存储的呢?

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以使用二进制形式存储。

如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出,则在磁盘上只占4个字节。

有时二进制存储数据会比文本存储数据更节省空间(10000);

Ascll码形式存储就是文本数据;

以二进制形式打开当前程序的文件(VS编译)右击程序选择二进制的快捷打开方式;

7.文件读取结束的判定

7.1被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

已经知道读取结束后;用feof函数来判断是读取失败结束,还是遇到文件尾结束

1.文本文件读取是否结束,判断返回值是否为EOF ( fgetc),或者NULL ( fgets )例如:

o fgetc判断是否为EOF .

o fgets判断返回值是否为NULL.

2.二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。例如:

o fread判断返回值是否小于实际要读的个数.(fread函数返回的是实际读到的个数);

如果小于就不能再向后读入了,本次为最后一次;

7.2 文本数据读入判断

int main(void){

int c;// 注意: int,非char,要求处理EOF
FILE* fp = fopen("test.txt","r");
if(!fp) 
{

perror("File opening failed"');return EXIT_FAILURE;

}

//fgetc当读取失败的时候或者遇到文件结束的时候,都会返回EOF

while ((c = fgetc(fp)) != EQF)//读取文件循环

{

putchar(c);

}

//判断是什么原因结束的

if (ferror(fp))//ferrror函数用来判断是不是再文件操作中遇到错误导致的读取结束;当返回值为真则我呢 //见操作错误

puts("error when reading");

else if (feof(fp))//feof函数用来判断文件读取是不是结束后才停止的;

puts("End of file reached successfully");

fclose(fp);

}

7.3 二进制读入判断

enum { SIZE = 5 };int main(void)

{

double a[SIzE] = {1.,2.,3.,4.,5.};

FILE*fp = fopen("test.bin","wb");//必须用二进制模式

fwrite(a,sizeof *a,SIZE,fp);//写double的数组

fclose(fp);

double b[SIZE];

fp = fopen("test.bin", "rb");

size_t ret_code = fread(b,sizeof *b,SIZE,fp);//读double 的数组

if(ret_codeI== SIZE)

{

puts("Array read successfu1ly,contents: ");

for(int n = 0; n< SIZE; ++n)

printf("%f ",b[n]);

putchar( ' \n');

}else // error handling

if (feof(fp))

printf("Error reading test.bin: unexpected end of file\n")

else if (ferror(fp))

{

perror("Error reading test.bin");

}

}

fclose(fp);

}

ferror函数和feof函数经常放在一起使用;各自有各自的作用;

ferrror函数用来判断是不是再文件操作中遇到错误导致的读取结束;

feof函数用来判断文件读取是不是结束后才停止的;返回值为真读到数据末尾停止;

8. 文件缓冲区

ANSIC标准采用"缓冲文件系统"处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块"文件缓冲区"。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

数据缓冲区的设立是为了提高我们系统读写的效率;

如果没有缓冲区的存在,我们在频繁读写过程中需要不断的打断操作系统的读写工作过程;使操作系统无法聚焦于当前的工作,导致效率的降低;当写满缓冲区时一次性交给操作系统去帮我们读写文件;效率大大提高;

验证文件缓冲区的真实存在:

这里可以得出一个结论:

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。

如果不做,可能导致读写文件的问题:当我们想要读写下一组数据时没有对上一个文件残留的缓冲区内容进行刷新也没有关闭上一个文件来重置缓冲区;在读写时缓冲区里残留的数据内容会也会读写到我们的第二个程序操作中;造成严重后果;

文件学习至此结束,关于文件的学习我们只需要学会相关函数的使用和了解一些新的语法规则;

真正参加工作时企业不会将大量的数据存放到文件,而是使用构建的数据库,它可以多个程序员

同时进行数据的增删查改,效率会大大提高;

我们日常写一些日志可以用到文件,后续学习c++使用的文件也是分装更精细的更底层的使用规则;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值