是否可以从二进制文件的多个部分读取数据?
为了举例,一个整数;的sizeof(int)的= 4;我想读取文件中某个位置的前n个字节,以及另一个位置的其他4-n个字节;然后以某种方式将它们组合在一起形成一个完整的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