读取二进制文件

时间:2017-07-05 20:07:37

标签: c++

我正在尝试读取文件的前6个字节,但它给了我奇怪的结果,我似乎无法弄清楚我做错了什么。

我的代码:

struct Block {
    char fileSize[3];
    char initialDataBlockId[3];
};

int main(int c, char **a) {

    ifstream file("C\\main_file_cache.idx0", ios::binary);

    Block block;

    file.get((char*)&block, sizeof(block));

    printf("File Size: %i\n", block.fileSize);
    printf("Initial Data Block ID: %i\n", block.initialDataBlockId);

    file.close();

    system("pause");
    return 0;
}

在运行代码之前,我在二进制编辑器中打开了文件, 它向我展示了这个十六进制代码:

    00 00 00 00-00 00 05 af-4b 00 00 01-26 df cd 00
    00 6f 03 3f-ed 00 03 61-05 08 35 00-04 8b 01 61
    59 00 08 39-03 23 0a 00-05 6c 00 35-d0 00 06 fe
    03 69 d8 00-07 19

总共有54个字节。前6个字节只是零。

所以,我希望我的程序产生以下输出:

File Size: 0
Initial Data Block ID: 0

相反,输出如下:

File Size: 10419128
Initial Data Block ID: 10419131

这个结果毫无意义。也许我的代码出了问题?

2 个答案:

答案 0 :(得分:4)

您应该在unsigned char结构中使用Block类型。

您应该使用file.read()来读取二进制数据而不是file.get()

您正在Block结构中打印数组的地址,而不是其内容,而且说明符%i需要int,而不是char *,所以未定义的行为,你得到一些奇怪的整数值,但任何问题都已发生,包括程序终止。建议增加警告级别,以便编译器警告这种愚蠢的错误。

如果文件格式是小端,你可以用这种方式将这3个字节的数组转换为数字:

int block_fileSize =  (unsigned char)block.fileSize[0] + 
                     ((unsigned char)block.fileSize[1] << 8) + 
                     ((unsigned char)block.fileSize[2] << 16);
int block_initialDataBlockId =  (unsigned char)block.initialDataBlockId[0] +
                               ((unsigned char)block.initialDataBlockId[1] << 8) +
                               ((unsigned char)block.initialDataBlockId[2] << 16);
printf("File Size: %i\n", block_fileSize);
printf("Initial Data Block ID: %i\n", block_initialDataBlockId);

答案 1 :(得分:1)

如果您想阅读二进制数据,则必须使用read中的ifstream方法和write中的ofstream方法。

istream & ifstream::read (char * s, streamsize n);
ostream & ofstream::write (const char * s, streamsize n);

您必须知道二进制模式对UNIX系统没用,文本模式才有用。