打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
C语言入门教程-二进制文件

二进制文件

二进制文件非常类似于结构体数组,只不过这些结构体被保存在一个磁盘文件而非内存数组中。因为是使用磁盘保存二进制文件中的结构体,所以您可以创建非常庞大数目的结构体(只受可用磁盘空间的限制)。它们还是永久性的,并且可以随时使用。惟一的缺点是磁盘存取会造成延迟。

二进制文件与文本文件有两个不同的特点:

  • 您可以立即跳至文件中的任一结构体,类似于数组的随机存取。
  • 您可以随时改变文件中任一处结构体的内容。

二进制文件通常还具有比文本文件更短的存取时间,因为文件记录的二进制映像是直接从内存传送至磁盘的(或相反的方向)。对于文本文件,所有数据都要反复转换成文本,而这需要花费时间。

C所支持的“结构体文件”概念十分简洁。某文件被打开后,您可以读取一个结构体,写入一个结构体,或移动至文件中的任一结构体。这种文件模型要求有一个文件指针的概念。打开文件时,指针指向0号记录(文件的第一个记录)。任何读操作都读取当前被指向的结构体,并将指针指向下一个结构体。任何写操作都向当前被指向的结构体写入数据,并将指针指向下一个结构体。移动操作将文件指针移至指定的记录。

请记住C总是将文件内容视为从磁盘读入内存或从内存写入磁盘的字节块。C使用文件指针,但指针可以指向文件中的任一字节。因此您需要自己管理好指针的位置。

下面的程序可以说明以上概念:

 

#include /* 任取一种文件记录结构,也可以是其他形式 */struct rec{    int x,y,z;};/* 向文件“junk”先写入   再读取10条随意的记录。*/int main(){    int i,j;    FILE *f;    struct rec r;    /* 创建一个包含10条记录的文件 */    f=fopen("junk","w");    if (!f)        return 1;    for (i=1;i<=10; i++)    {        r.x=i;        fwrite(&r,sizeof(struct rec),1,f);    }    fclose(f);    /* 读取这10条记录 */    f=fopen("junk","r");    if (!f)        return 1;    for (i=1;i<=10; i++)    {        fread(&r,sizeof(struct rec),1,f);        printf("%d\n",r.x);    }    fclose(f);    printf("\n");    /* 使用fseek逆序读取10条记录 */    f=fopen("junk","r");    if (!f)        return 1;    for (i=9; i>=0; i--)    {        fseek(f,sizeof(struct rec)*i,SEEK_SET);        fread(&r,sizeof(struct rec),1,f);        printf("%d\n",r.x);    }    fclose(f);    printf("\n");    /* 使用fseek隔条读取记录 */    f=fopen("junk","r");    if (!f)        return 1;    fseek(f,0,SEEK_SET);    for (i=0;i<5; i++)    {        fread(&r,sizeof(struct rec),1,f);        printf("%d\n",r.x);        fseek(f,sizeof(struct rec),SEEK_CUR);    }    fclose(f);    printf("\n");    /* 使用fseek读取第4条记录,       修改记录内容并写回 */    f=fopen("junk","r+");    if (!f)        return 1;    fseek(f,sizeof(struct rec)*3,SEEK_SET);    fread(&r,sizeof(struct rec),1,f);    r.x=100;    fseek(f,sizeof(struct rec)*3,SEEK_SET);    fwrite(&r,sizeof(struct rec),1,f);    fclose(f);    printf("\n");    /* 读取10条记录       检查第4条记录是否已被修改 */    f=fopen("junk","r");    if (!f)        return 1;    for (i=1;i<=10; i++)    {        fread(&r,sizeof(struct rec),1,f);        printf("%d\n",r.x);    }    fclose(f);    return 0;}

此程序使用了一个名为rec的结构体类型,但您也可以使用任一种结构体类型。您可以看到fopen和fclose的使用和在文本文件中是一样的。

新引入的函数是fread、fwrite和fseek。fread函数接受四个参数:

  • 一个内存地址
  • 读入的内存块包含的字节数
  • 读入的内存块个数
  • 文件变量

因此,fread(&r,sizeof(struct rec),1,f);表示:把12个字节(rec类型的大小)的内容从文件f(文件指针指向的当前位置)读入内存地址&r,共要求读入一个12字节大小的块。只要把1改成100,就可以很容易地使这条语句变为:将100个块从磁盘读入一个内存数组中。

fwrite和fread类似,只不过它是将字节块从内存写入文件中。fseek函数负责把文件指针移至文件中的某个字节。指针每次移动的距离一般都是sizeof(struct rec)的整数倍,这样指针就可以保持总是指向记录的开始处。移动指针有三种方式:

  • SEEK_SET
  • SEEK_CUR
  • SEEK_END

SEEK_SET表示指针从文件开始处(0字节处)向后移动x个字节。SEEK_CUR表示指针从当前位置向后移动x个字节。SEEK_END表示指针从文件末尾向前移动(所以偏移量应为负数)。

上面代码中使用了多个函数选项。其中请特别注意一下用r+模式打开文件的段落。这种模式支持文件的读取和写入,即可以修改文件中的记录。程序首先把文件指针移至某个记录,然后读取这条记录内容并修改了一个成员。之后重新把指针移动指向此记录,因为刚才的读取已经更新了指针。最后把修改过的记录写回。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
关于获取yuv帧数问题
有关fwrite语句的用法
C读取MP3头部和尾部信息的代码
c语言中所有文件操作函数详解fopen、fwrite、fread、fgetc、fputc、fscanf、fprintf、ftell、fseek等函数
结构,删除与添加文件清单
fseek() 函数用法
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服