C++ 附加二进制文件

C++ 附加二进制文件,c++,file-io,C++,File Io,我必须把数字数据写入二进制文件。因为我处理的一些数据向量可以是几千兆大小,所以我学会了不使用C++ IoSokes。相反,我想使用C文件*。我马上遇到了一个问题,我需要在二进制文件的前面写一些元数据。由于一些元数据一开始是未知的,我需要在将元数据添加到文件中适当的偏移量时将其追加 例如,假设我必须输入年、月和日的uint16表示形式,但首先我需要跳过第一个输入uint32值以获得精度 我不知道我做错了什么,但我似乎无法在文件中附加ab。 下面是我写的一个例子: #include<cstdi

我必须把数字数据写入二进制文件。因为我处理的一些数据向量可以是几千兆大小,所以我学会了不使用C++ IoSokes。相反,我想使用C文件*。我马上遇到了一个问题,我需要在二进制文件的前面写一些元数据。由于一些元数据一开始是未知的,我需要在将元数据添加到文件中适当的偏移量时将其追加

例如,假设我必须输入年、月和日的uint16表示形式,但首先我需要跳过第一个输入uint32值以获得精度

我不知道我做错了什么,但我似乎无法在文件中附加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
附加的数据不写入。如果我将其更改为wb,则该文件将被覆盖。我能够让它与r+b一起工作,但我不明白为什么。我认为ab是合适的。另外,我应该使用缓冲区还是这是一种足够的方法

谢谢你的建议


顺便说一句,这是在MacOSX上,r+b意味着您可以读取和写入文件中的任何位置。在第二个代码块中,倒带调用将当前位置设置为字节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;-位置到日值

r+b表示您可以读取和写入文件中的任何位置。在第二个代码块中,倒带调用将当前位置设置为字节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;-由于硬盘和文件系统的工作方式,在文件中间插入字节的速度非常慢,应该避免,尤其是在处理多GB文件时。如果元数据存储在固定大小的标题中,则在开始使用其他数据之前,请确保有足够的空间存储元数据。如果标题大小可变,则将标题分块。将1k的头空间放在开头,并保留8个字节以包含到下一个头块的偏移量值,或0表示EOF。然后,当该块被填满时,只需将另一个块添加到文件末尾,并将其偏移量写入上一个头

至于技术IO,根据需要使用r+b、w+b或a+b的fopen模式。他们的行为都是一样的,只是略有不同。r+b从第一个字节开始打开文件进行读写。如果文件不存在,它将出错。w+b将执行相同的操作,但如果文件不存在,则创建该文件。a+b与r+b相同,但它以文件末尾的文件指针开始


您可以使用fseek导航文件并回放。倒带将文件指针移回文件的开头。fseek将文件指针移动到指定位置。您可以阅读更多有关它的信息

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

至于技术IO,根据需要使用r+b、w+b或a+b的fopen模式。他们的行为都是一样的,只是略有不同。r+b从第一个字节开始打开文件进行读写。如果文件不存在,它将出错。w+b将执行相同的操作,但如果文件不存在,则创建该文件。a+b与r+b相同,但它以文件末尾的文件指针开始

您可以使用fseek导航文件并回放。倒带将文件指针移回文件的开头
文件fseek将文件指针移动到指定位置。您可以阅读更多关于它的信息

对于如此大的文件,仅仅为了预加几个字节而重写GIG是非常低效的

最好为每个文件创建一个包含所需元数据的小型配套文件,并且如果要作为编辑的一部分重写元数据字段,则只将其添加到文件的开头

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

对于如此大的文件,只需预先添加几个字节就可以重写GIG,效率极低

最好为每个文件创建一个包含所需元数据的小型配套文件,并且如果要作为编辑的一部分重写元数据字段,则只将其添加到文件的开头

这是因为在大多数文件系统中,文件预处理的成本非常高。

NTFS为大多数文件提供了第二个数据通道,除了MS内部程序(如文件管理器和安全扫描程序)之外,几乎所有程序都看不到这些文件。您可以轻松编写一个程序,将元数据添加到该频道,而无需每次都覆盖磁盘上的GIG。

为什么选择不使用iostreamYou只能附加到该频道的末尾file@Cole约翰逊太慢了。C文件smoke iostreamAppend上的基准表示在文件的最后追加。他们跟踪,他们不领导。尝试使用+模式。以特定字节重新访问文件的正确方法是什么?为什么选择不使用iostreamYou只能附加到file@Cole约翰逊太慢了。C文件smoke iostreamAppend上的基准表示在文件的最后追加。他们跟踪,他们不领导。尝试使用a+模式。以特定字节重新访问文件的正确方法是什么?a+b与r+b不同。如果文件不存在,a+b将创建它,r+b将失败。此外,a+b将文件定位在读取的开始位置,但所有写入操作都添加到文件的结尾。可以我只需要在文件的开头附加几次头信息。一旦我得到了实际处理数字数据的代码,它都是顺序的,我不会试图访问任何不按顺序的东西。当我完成时,我可能需要添加一些最终标题信息。就这样。谢谢你@Alec Danyshchuk;您提供了一个链接来清楚地说明我要做的唯一的模式是R+或R+B.C++引用:对于W+来说,如果一个具有相同名称的文件已经存在,它的内容被丢弃,文件被当作一个新的空文件。这是a+a+b与r+b的另一个不同之处。如果文件不存在,a+b将创建它,r+b将失败。此外,a+b将文件定位在读取的开始位置,但所有写入操作都添加到文件的结尾。可以我只需要在文件的开头附加几次头信息。一旦我得到了实际处理数字数据的代码,它都是顺序的,我不会试图访问任何不按顺序的东西。当我完成时,我可能需要添加一些最终标题信息。就这样。谢谢你@Alec Danyshchuk;您提供了一个链接来清楚地说明我要做的唯一的模式是R+或R+B.C++引用:对于W+来说,如果一个具有相同名称的文件已经存在,它的内容被丢弃,文件被当作一个新的空文件。因此,这是另一个不同之处+
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);

}