1

我必须将数值数据写入二进制文件。由于我处理的一些数据向量的大小可能是几千兆,因此我学会了不使用 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”是合适的。另外,我应该使用缓冲区还是足够的方法?

感谢您的建议

顺便说一句,这是在 MacOSX 上

4

3 回答 3

3

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

至于技术 IO,根据需要使用、、 或的fopen()模式。它们的行为都相同,只是略有不同。打开文件进行读写,从第一个字节开始。如果文件不存在会出错。会做同样的事情,但如果文件不存在则创建文件。与 相同,但它以文件末尾的文件指针开头。r+bw+ba+br+bw+ba+br+b

fseek()您可以使用和导航文件rewind()rewind()将文件指针移回文件的开头。fseek()将文件指针移动到指定位置。你可以在这里阅读更多关于它的信息。

于 2012-08-24T08:42:41.073 回答
1

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

如果你使用“a+b”,这也意味着读写访问,但写入都在文件的末尾,所以你不能定位在字节 0,除非创建一个新的空文件。

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

fseek ( 文件流 , 0 , SEEK_SET ); - 定位到精度值

fseek ( 文件流 , 4 , SEEK_SET ); - 位置到年份值

fseek ( 文件流 , 8 , SEEK_SET ); - 月值的位置

fseek ( 文件流 , 12 , SEEK_SET ); - 持仓日值

于 2012-08-24T08:02:43.233 回答
0

对于如此大的文件,重写 gigs 只是为了预先添加几个字节是非常低效的。

最好为每个文件创建一个您需要的元数据的小伴随文件,并且仅当它们作为编辑的一部分被重写时才将元数据字段添加到文件的开头。

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

于 2020-10-03T20:04:42.153 回答