正在追加二进制文件
Appending Binary files
我必须将数字数据写入二进制文件。由于我处理的一些数据向量的大小可能是几GB,所以我学会了不使用C++iostream。相反,我想使用C文件*。我马上就遇到了一个问题,我需要在二进制文件的前面写一些元数据。由于一些元数据一开始是未知的,我需要在获得元数据时将其附加到文件中适当的偏移量。
例如,假设我必须输入年份、月份和日期的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 上
由于硬盘驱动器和文件系统的工作方式,在文件中间插入字节确实很慢,应该避免,尤其是在处理千兆字节的文件时。如果您的元数据存储在固定大小的标头中,那么在开始处理其他数据之前,只需确保有足够的空间即可。如果标头大小可变,则对标头进行分块。将1k的标头空间放在开头,并保留8个字节以包含到下一个标头块的偏移值,或者0表示EOF。然后,当这个块被填满时,只需在文件的末尾添加另一个块,并将其偏移量写入前一个标头。
对于技术IO,根据需要使用r+b
、w+b
或a+b
的fopen()
模式。他们的行为都一样,只是略有不同。r+b
打开文件进行读取和写入,从第一个字节开始。如果文件不存在,它将出错。w+b
也会执行同样的操作,但如果文件不存在,则创建该文件。a+b
与r+b
相同,但它从文件末尾的文件指针开始。
您可以使用fseek()
和rewind()
导航文件。rewind()
将文件指针移回文件的开头。fseek()
将文件指针移动到指定位置。你可以在这里阅读更多关于它的信息。
"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);-仓位到日值
对于如此大的文件,只为准备几个字节而重写gig将是非常低效的。
最好为每个文件创建一个包含所需元数据的小配套文件,如果要在编辑过程中重写元数据字段,则只在文件的开头添加元数据字段。
这是因为在大多数文件系统中,为文件做准备是非常昂贵的。NTFS为大多数文件提供了第二个数据通道,除了文件管理器和安全扫描程序等MS内部程序外,几乎所有程序都看不到该通道。您可以很容易地编写一个程序,将您的元数据添加到该频道,而无需每次都覆盖磁盘上的演出。
- 正在读取二进制文件(is_open)
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- Android 在编译二进制文件时重建静态库
- 在 C++ 中将双精度变量写入二进制文件
- clang 的 libFuzzer 可以在同一二进制文件中测试超过 1 个 API 吗?
- C++:实际上不是从二进制文件中读取
- 如何从二进制文件中的给定符号中获取调用程序图
- 将内部带有矢量的结构保存/读取到二进制文件中
- 编译多个C++文件.调用二进制文件以运行代码
- 如何使用位字段将数据从二进制文件复制到结构中?
- uint8_t同一二进制文件的不同十进制值
- C++单个生成文件多个二进制文件
- 尝试将数字写入二进制文件时引发异常
- C++中读/写二进制文件
- 如何忽略某些二进制文件的执行?
- 分段 追加和读取二进制文件时出错
- 正在追加二进制文件