写二进制文件的行为很奇怪

Very strange behavior writing binary file

本文关键字:二进制文件      更新时间:2023-10-16

我在输出二进制数据时遇到了一个非常复杂的问题。我正在编写一个模型转换器,它采用ASCII文件格式并将值转换为二进制。解析完文件后,我将这些值以二进制形式写出来。在某种程度上,一切都很好,然后事情就变得奇怪了。

正在输出的数据块看起来像这样:

struct vertex_t
{
    glm::vec2 texcoord;
    unsigned short weight_index_start;
    unsigned char weight_count;
};

这是所讨论的二进制数据块,#符号后面有一个人类可读的值。

00 00 80 3F # 1.000
AA AA AA 3E # 0.333
00 00       # 0
01          # 1
00 00 40 3F # 0.750
AA AA AA 3E # 0.333
01 00       # 1
01          # 1
00 00 40 3F # 0.750
00 00 00 00 # 0.000
02 00       # 2
01          # 1
...

一切看起来都很好,直到11元素,那里发生了一些奇怪的事情…

00 00 00 3F # 0.500
AA AA AA 3E # 0.333
09 00       # 9
01          # 1
FE FF 7F 39 # 2.4x10^-4
AA AA 2A 3F # 0.666
0D          # 13 (why is this here?!)
0A 00       # 10
01          # 1
00 00 40 3F # 0.75
00 00 80 3F # 1.0
0B 00       # 11
01          # 1

可以看到,在结构体中间没有明显的原因地写了一个0D。下面是导出该结构体的相关代码块:

for (const auto& vertex : mesh.vertices)
{
    ostream.write(reinterpret_cast<const char*>(&vertex.texcoord.x), sizeof(vertex.texcoord.x));
    ostream.write(reinterpret_cast<const char*>(&vertex.texcoord.y), sizeof(vertex.texcoord.y));
    ostream.write(reinterpret_cast<const char*>(&vertex.weight_index_start), sizeof(vertex.weight_index_start));
    ostream.write(reinterpret_cast<const char*>(&vertex.weight_count), sizeof(vertex.weight_count));
}

我不知道这是怎么发生的,但也许我错过了什么。任何帮助将不胜感激!

你好像把回车符和换行符塞进了文件。

OD : Carriage return
0A : NL line feed, New line

参见http://www.asciitable.com/

尝试打开带有ios::binary参数的文件

的例子:

fstream output("myfile.data", ios::out | ios::binary);

希望这对你有帮助!

您没有显示如何写入数据。一般来说,但是,如果输出格式不是文本格式,则必须以二进制模式打开文件;乍一看,它好像你使用的是Windows系统,还没有这样做过。二进制0x0A对应'n',如果文件未打开在二进制模式下,这将被转换为与系统相关的在Windows(可能还有大多数其他)下的新行指示符&mdash非Unix系统),转换为两个字节序列0x0D, 0x0A。

除非您的输出格式是文本,否则您必须以二进制模式,读时和写时都是。(通常是忘记了)充满了"C"语言环境;否则,可能会有代码翻译。

RE你的更新,用写方法:这做不是输出任何保证你以后还能读的东西。(需要一个reinterpret_cast应该提示你。)如果你只是将一个太大的数据集溢出到磁盘,无法重新读取以后按同样的工艺,精细(只要结构只包含整型、浮点型和枚举型)。在所有其他情况下,您需要定义二进制格式(或使用(已经定义的,如XDR),格式化输出到它,并且在输入时解析它。(用一种完全便携的方式因为浮点数绝对是非平凡的。另一方面,大多数应用程序不需要完全的可移植性,如果有的话二进制格式是基于IEEE的,所有的目标系统如果使用IEEE,您通常可以对比特进行解释浮点数的模式为适当大小的无符号数