二进制文件与文本文件有两个不同的特点:
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);
",r.x);
}
fclose(f);
printf("
");
/* 使用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);
",r.x);
}
fclose(f);
printf("
");
/* 使用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);
",r.x);
fseek(f,sizeof(struct rec),SEEK_CUR);
}
fclose(f);
printf("
");
/* 使用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("
");
/* 读取10条记录
检查第4条记录是否已被修改 */
f=fopen("junk","r");
if (!f)
return 1;
for (i=1;i<=10; i++)
{
fread(&r,sizeof(struct rec),1,f);
",r.x);
}
fclose(f);
return 0;
}
此程序使用了一个名为rec的结构体类型,但您也可以使用任一种结构体类型。您可以看到fopen和fclose的使用和在文本文件中是一样的。
新引入的函数是fread、fwrite和fseek。fread函数接受四个参数:
fwrite和fread类似,只不过它是将字节块从内存写入文件中。fseek函数负责把文件指针移至文件中的某个字节。指针每次移动的距离一般都是sizeof(struct rec)的整数倍,这样指针就可以保持总是指向记录的开始处。移动指针有三种方式:
上面代码中使用了多个函数选项。其中请特别注意一下用r+模式打开文件的段落。这种模式支持文件的读取和写入,即可以修改文件中的记录。程序首先把文件指针移至某个记录,然后读取这条记录内容并修改了一个成员。之后重新把指针移动指向此记录,因为刚才的读取已经更新了指针。最后把修改过的记录写回。
有关C语言及相关主题的更多信息,请查看下一页上的链接。
编辑推荐