二进制文件
二进制文件非常类似于结构的数组,只不过结构是在磁盘文件中,而不是在内存中的数组中。因为二进制文件中的结构位于磁盘上,所以可以创建非常大的结构集合(仅受可用磁盘空间的限制)。它们也是永久的,总是可用的。唯一的缺点是来自磁盘访问时间的缓慢。
二进制文件有两个特征来区别于文本文件:
广告
- 您可以立即跳转到文件中的任何结构,这就像在数组中一样提供了随机访问。
- 您可以在任何时间更改文件中任何位置的结构的内容。
二进制文件通常比文本文件具有更快的读写时间,因为记录的二进制图像直接从内存存储到磁盘(反之亦然)。在文本文件中,所有内容都必须来回转换为文本,这需要时间。
C语言非常清晰地支持结构文件的概念。一旦打开文件,就可以读取结构,写入结构,或查找文件中的任何结构。这个文件概念支持文件指针.当打开文件时,指针指向记录0(文件中的第一条记录)。任何读操作读取当前指向的结构,并将指针向下移动一个结构。任何写操作写入当前指向的结构,并将指针向下移动一个结构。寻求将指针移动到所请求的记录。
请记住,C语言将磁盘文件中的所有内容视为从磁盘读取到内存或从内存读取到磁盘的字节块。C语言使用文件指针,但它可以指向文件中的任何字节位置。因此,你必须跟踪事情。
下面的程序说明了这些概念:
#include/*任意记录描述*/ struct rec {int x,y,z;};/*从“junk”文件中写入并读取10条任意记录。*/ int main() {int i,j;文件* f;结构rec r;/*创建10条记录的文件*/ f=fopen("junk","w");If (!f)返回1;(我= 1,< = 10;i++) {r.x= I; fwrite(&r,sizeof(struct rec),1,f); } fclose(f); /* read the 10 records */ 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"); /* use fseek to read the 10 records in reverse order */ 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"); /* use fseek to read every other record */ 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"); /* use fseek to read 4th record, change it, and write it back */ 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"); /* read the 10 records to insure 4th record was changed */ 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; }
在这个程序中,一个结构描述矩形已使用,但您可以使用任何您想要的结构描述。你们可以看到打开外部文件而且文件关闭工作方式与文本文件完全相同。
新函数是从文件中读,写入文件而且fseek.fread函数有四个参数:
- 内存地址
- 每个块要读取的字节数
- 要读取的块数
- 文件变量
因此,直线从文件中读(设计验证,sizeof (struct rec), 1, f);表示读取12字节(大小为矩形)f(从当前位置的文件指针)转换到内存地址描述:.请求一个12字节的块。通过将1改为100,可以很容易地将100个块从磁盘读入内存中的数组。
的写入文件函数以同样的方式工作,但将字节块从内存移动到文件。的fseek函数将文件指针移动到文件中的一个字节。一般来说,你把指针往里移动sizeof (struct rec)使指针保持在记录边界的增量。您可以使用以下三个选项:
- SEEK_SET
- SEEK_CUR
- SEEK_END
SEEK_SET移动指针x从文件开始往下的字节(从文件中的字节0开始)。SEEK_CUR移动指针x从当前指针位置向下字节数。SEEK_END将指针从文件末尾移动(因此此选项必须使用负偏移量)。
上面的代码中出现了几个不同的选项。特别要注意打开文件的部分r +模式。这将打开文件进行读写,从而允许更改记录。代码寻找一条记录,读取它,并更改一个字段;然后,由于读操作移位了指针,它会返回,并将更改写回。