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

时间:2015-05-06 21:28:47

标签: c++ c binaryfiles

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

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

这可能吗?

4 个答案:

答案 0 :(得分:3)

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

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);

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

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

答案 1 :(得分:2)

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

您只需分两步即可将数据(包含fread()read()或任意内容)读入4 char数组。然后,您可以memcpy()将此int发送给您char array[4]。如果您不害怕投射和指针算术,可以跳过memcpy()SELECT * FROM wp_postmeta WHERE post_id = 73 AND (( meta_key = 'wpcf-mw' AND meta_value BETWEEN -8 AND 200 ) **OR** ( meta_key = 'wpcf-milk' AND meta_value BETWEEN 20 AND 200 )) 的使用。

答案 2 :(得分:0)

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

答案 3 :(得分:-1)

我会采用以下方式:

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