那些不为人知的文件操作知识2

朋友们,承接上文。我上篇文章发布出去的时候想到缓冲区的内容忘记讲了,不过没关系,放在这一篇文章里面更加能体现内存空间的变化。

文件缓冲区

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

文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSIC 规定使用fopen函数来打开文件,fclose来关闭文件。

FILE * fopen ( const char * filename, const char * mode );
int fclose ( FILE * stream );

具体的方式如下,这个就像我们在使用printf的时候所标注的%d这种是一样的意义。

我们这里照样举个代码的例子来解释一下:

/* fopen fclose example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  pFile = fopen ("myfile.txt","w");
  if (pFile!=NULL)
 {
    fputs ("fopen example",pFile);
    fclose (pFile);
 }
  return 0;
}

这个代码比较简单,不做过多解释,可以放在ai里面自己去尝试理解,主要要理解这个逻辑。

文件的顺序读写

文件的顺序读写是指按照数据在文件中的存储顺序,依次读取或写入数据。这种操作通常用于处理文本文件、日志文件等需要逐行或逐个记录处理的场景。

https://zh.cppreference.com/w/c

上面是c++的网站,这里解释一下什么是输入输出流。

输入流和输出流是计算机编程中用于处理数据输入和输出的抽象概念。它们将数据的来源或目标抽象成一个“流”(类似水流),程序可以像操作连续的数据管道一样,从流中读取数据或向流中写入数据,而无需关心底层细节(如文件、网络、键盘等物理设备的具体实现)。

程序通过输入流读取数据,通过输出流写入数据。

文件的随机读写

fseek


根据文件指针的位置和偏移量来定位文件指针。

int fseek ( FILE * stream, long int offset, int origin );

stream:指向 FILE 结构的指针,通常由 fopen 返回。
offset:相对于 whence 的偏移量,可以是正数、负数或零。
whence:指定 offset 的起始点,可以是以下值之一:

SEEK_SET:文件开头(默认为0)。
SEEK_CUR:当前文件指针位置。
SEEK_END:文件结尾。

举个例子:

/* fseek example */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  pFile = fopen ( "example.txt" , "wb" );
  fputs ( "This is an apple." , pFile );
  fseek ( pFile , 9 , SEEK_SET );
  fputs ( " sam" , pFile );
  fclose ( pFile );
  return 0;
}

ftell


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

long int ftell ( FILE * stream );

stream:指向 FILE 结构的指针,通常由 fopen 返回。

成功时返回当前文件指针相对于文件开头的字节偏移量。

如果发生错误,则返回 -1L,并设置全局变量 errno 来指示错误类型。

/* ftell example : getting size of a file */
#include <stdio.h>
int main ()
{
  FILE * pFile;
  long size;
  pFile = fopen ("myfile.txt","rb");
  if (pFile==NULL) perror ("Error opening file");
  else
 {
    fseek (pFile, 0, SEEK_END);   // non-portable
    size=ftell (pFile);
    fclose (pFile);
    printf ("Size of myfile.txt: %ld bytes.\n",size);
 }
  return 0;
}

rewind

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

void rewind ( FILE * stream );
/* rewind example */
#include <stdio.h>
int main ()
{
  int n;
  FILE * pFile;
  char buffer [27];
  pFile = fopen ("myfile.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;

这段代码是向文件写入26个大写字母(A-Z),再将内容读回并显示在屏幕上。这里解释一下”w+“

模式 "w+":以读写方式打开文件。若文件不存在则创建新文件;若存在则清空内容。

最后在讲一个错误判定

被错误使用的 feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。

而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。
1. 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)

例如:
fgetc判断是否为EOF.
fgets判断返回值是否为NULL.

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

例如:
fread判断返回值是否小于实际要读的个数。

#include <stdio.h>
#include <stdlib.h>
 
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)) != EOF) // 标准C I/O读取文件循环
   { 
       putchar(c);
   }
 //判断是什么原因结束的
    if (ferror(fp))
        puts("I/O error when reading");
    else if (feof(fp))
        puts("End of file reached successfully");
 
    fclose(fp);
}

这里照样放一个代码。供大家学习,那么这篇文章就到这里结束了,可以点赞关注收藏一下,关于scanf/fscanf/sscanf
printf/fprintf/sprintf

这些函数的区别,我会过两天更改这篇博客,届时,也会更加完善代码和函数的讲解,现在大家可以试着去自己理解。感谢支持,我们下篇再见!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值