附加二进制文件

时间:2012-08-24 05:37:43

标签: c++ file-io

我必须将数值数据写入二进制文件。由于我处理的一些数据向量可以是几个演出,我已经学会了不使用C ++ iostream。相反,我想使用C File *。我正在遇到一个问题,我需要在二进制文件的前面写一些元数据。由于一些元数据一开始就不知道,所以当我将元数据添加到文件中的相应偏移量时,我需要附加元数据。

例如,假设我必须输入年,月和日的uint16_t表示,但首先我需要跳过第一个条目(uint32_t值表示精度);

我不知道我做错了什么,但我似乎无法用“ab”附加文件。 这是我写的一个例子:

#include<cstdio>

uint16_t year = 2001;
uint16_t month = 8;
uint16_t day = 23;

uint16_t dateArray[]={year , month, day};

File * fileStream;
fileStream = fopen("/Users/mmmmmm/Desktop/test.bin" , "wb");

if(fileStream){

// skip the first 4 bytes
fseek ( fileStream , 4 , SEEK_SET );

fwrite(dateArray, sizeof(dateArray[0]) ,( sizeof(dateArray) / sizeof(dateArray[0]) ), filestream);

fclose(filestream);

}
 // loops and other code to prepare and gather other parameters

//现在以精确度附加文件的前面。

uint32_t precision = 32;

File *fileStream2;
fileStream2 = fopen("/Users/mmmmmm/Desktop/test.bin" , "ab"); 

if(fileStream2){

// Get to the top of the file
rewind(fileStream2);

fwrite(&precision, sizeof(precision) , 1 , fileStream2);

fclose(fileStream2);

}

附加数据不会写入。如果我将其更改为“wb”,则文件将被覆盖。我能够让它与“r + b”一起工作,但我不明白为什么。我认为“ab”是合适的。另外,我应该使用缓冲区还是一种充分的方法?

感谢您的建议

BTW这是在MacOSX上

3 个答案:

答案 0 :(得分:3)

由于硬盘驱动器和文件系统的工作方式,将字节插入文件中间的速度非常慢,应该避免,尤其是在处理数GB的文件时。如果您的元数据存储在固定大小的标头中,只需确保在开始使用其他数据之前有足够的空间。如果标题的大小可变,则将标题组合起来。在开头放置1k标头空间,并保留8个字节以包含到下一个标头块的偏移值,或者对于EOF包含0。然后,当该块被填满时,只需将另一个块添加到文件的末尾,并将其偏移量写入前一个头。

对于技术IO,请根据您的需要使用fopen()r+bw+b的{​​{1}}模式。它们的行为都是微不足道的。 a+b从第一个字节开始打开文件进行读写。如果文件不存在,则会出错。 r+b也会这样做,但如果文件不存在,则创建该文件。 w+ba+b相同,但它以文件末尾的文件指针开头。

您可以使用r+bfseek()导航文件。 rewind()将文件指针移回文件的开头。 rewind()将文件指针移动到指定位置。您可以阅读更多相关信息here.

答案 1 :(得分:1)

“r + b”表示您可以读取和写入文件中的任何位置。在第二个代码块中,rewind()调用将当前位置设置为字节0,并在此位置完成写入。

如果使用“a + b”,这也意味着读写访问,但写入都在文件末尾,因此除非创建新的空文件,否则无法定位到字节0。

要在特定字节重新访问该文件,只需使用fseek()。

fseek(fileStream,0,SEEK_SET); - 位置精确值

fseek(fileStream,4,SEEK_SET); - 年份值的位置

fseek(fileStream,8,SEEK_SET); - 月份值的位置

fseek(fileStream,12,SEEK_SET); - 日期值的位置

答案 2 :(得分:0)

使用如此大的文件,仅在几个字节之前重写演出是非常低效率的。

最好为每个文件创建一个小的伴随文件,其中包含每个文件所需的元数据,并且仅将元数据字段添加到文件的开头,以便无论如何都要在编辑时对其进行重写。

这是因为在大多数文件系统上,前置文件非常昂贵。 NTFS为大多数文件提供了第二个数据通道,几乎所有程序都看不到它,除了MS内部文件(例如文件管理器和安全扫描程序)。您可以轻松地编写一个程序以将元数据添加到该通道,而无需每次都覆盖磁盘上的演出。