将数字作为原始二进制文件写入文件

Writing number as raw binary to file

所以我试图将 long 的值作为原始二进制文件写入带有 fwrite() 的文件,这是一个测试文件:

#include<stdio.h>
int main() {
    FILE* stream;
    stream = fopen("write", "wb");
    long number = 0xfff;
    fwrite(&number, sizeof(long), 1, stream);
}

在文本编辑器中打开写入的文件时,这是输出:

ff0f 0000 0000 0000 

虽然我期待 0000 0000 0000 0fff

如何将所需结果正确写入原始二进制文件?

没问题。您将其视为 ff0f 0000 0000 0000 机器字节顺序的原因! 请尝试使用 fread()

正如其他人在评论中指出的那样,这是字节顺序 "issue"。也就是说,如果您要 运行 您的软件在具有其他字节顺序的系统上,这只是一个问题。

This very useful resource 是 "c endian" google 搜索的第一个结果,至少对我来说是这样。希望对你有帮助。


编辑:我将在下面更深入地探讨细节。

要确定您当前运行正在使用的机器的字节顺序,请将一个已知值(例如,0xAABBCCDD)写入内存,然后获取指向该值的指针,然后将其转换为 char* 或其他 1 字节数据类型。逐字节再次读取相同的值,并将顺序与您写入的顺序进行比较。如果它们相同,则说明您使用的是大端机器。如果不是......那么你可能在一个小的(更有可能的)或中等的(不太可能的)字节序机器上。在任何一种情况下,您都可以生成一个 "swap map" 来重新排序字节;这就是为什么我在上面的例子中选择了四个不同的字节值的原因。

但是,如何交换这些值?如 here 所示,一种简单的方法是使用带掩码的位移位。您还可以使用表格并交换它们的值。

阅读有关 Endianness 的内容,其中说明了计算机系统中字节在字(或 double/quad 字等)中的排列方式。

我假设您已经在 little-endian 的 X86 系统上编写和编译了此示例,因此,最低有效位优先。与该排列相反的是 big-endian.

现在,很明显您在本练习中的 objective 是 marshall(或 pickle,具体取决于如何你更喜欢你的行话)一些字节稍后可能由另一个程序检索。

如果您开发一个使用 fread() 的程序并以相同的方式读取数据(使用 sizeof(long) 这样您就不会读取太多数据)并且 同样的字节顺序,它会神奇地起作用,你期望的数字会回来。但是,如果您在具有相反字节顺序的机器上编译和 运行 "read" 工具,读取相同的输入文件,您的数字将是乱码。

如果您的 objective 是编组数据,您最好使用一个工具来帮助您以 endianness-agnostic 的方式编组字节,也就是说,一个库可以帮助您以正确的顺序获取数据。那里有图书馆可以为您处理。