如何从不同部分的二进制文件中读取 var? (比方说,2 个字节,另外 2 个字节来自另一个地方?)

How can I read a var from a binary file from different parts? (Say, 2 bytes, and another 2 bytes from another place?)

是否可以从二进制文件的多个部分读取数据?

为了举例,一个整数; sizeof(int)=4;我想从文件的一个地方读取前 n 个字节,从另一个地方读取其他 4-n 个字节;然后以某种方式将它们组合在一起形成一个完整的 4 字节整数。

这可能吗?

这显然是可能的,并且可以通过许多不同的方式实现。

您可以分两步将数据(使用 fread()read() 或任何您想要的)读取到 4 char 的数组中。然后你就可以 memcpy() 这个到你的 int。如果你不怕转换和指针运算,char array[4]memcpy() 的使用可以跳过。

我会按以下方式处理:

std::ifstream fstr("file", std::ios_base::binary);

int value;  

fstr.read(reinterpret_cast<char*>(&value), 2); //first two bytes

//read other stuff

fstr.read(reinterpret_cast<char*>(&value)+2, 2); //second two bytes

是的,这是可能的,并且可以以非常便携的方式完成 (*):

union int_bytes
{
    uint32_t value;
    unsigned char bytes[4];
};

long int first_part_offset = ... ;
long int second_part_offset = ... ;
size_t first_part_size = ... ;

FILE* file = fopen("filename", "rb");

int_bytes result;

fseek(file, first_part_offset, SEEK_SET);
fread(&(result.bytes[0]), 1, first_part_size, file);

if(first_part_size < 4) // nothing to read if first part was 4-byte long...
{
    fseek(file, second_part_offset, SEEK_SET);
    fread(&(result.bytes[first_part_size]), 1, first_part_size, file);
}

uint32_t final_int_value = int_bytes.value;

(*) 有什么非便携的可以在这里做?请记住,序列化数据始终取决于当前架构的 byte ordering (endianness)

如果你写这段代码:

int value = ... ;
fwrite(&value, sizeof(int), 1, file_handle);

文件内容将取决于字节顺序。是的,现在大多数平台都是小端,但不是全部!如果你知道,某些二进制数据被序列化为大端,而你当前的硬件是小端(反之亦然),你将需要交换读取的字节(大多数编译器允许有效地执行此操作,但是,提供内在的,即直接映射到 BSWAP instruction).

联合是许多字节操作中最好的朋友,假设至少具有 最小 可移植性。

您始终可以将它们读入两个变量并计算结果。我认为将它们读入一个 var 不是很有用或实用。如果两部分足够接近,可以将它们读入一个缓冲结构中,避免两次读取。