处理字节顺序和文件 C++ 的最常用方法

most common way to deal with endianness and files C++

我开始只是 reading/writing 8 位整数到使用字符的文件。不久我就意识到我需要能够处理的不仅仅是 256 个可能的值。我做了一些关于如何 read/write 16 位整数到文件的研究,并开始意识到 big 和 little endian 的概念。我做了更多的研究,发现了一些处理字节顺序的不同方法,我还学习了一些编写字节顺序无关代码的方法。我的总体结论是,我必须首先检查我使用的系统是使用大端还是小端,根据系统使用的类型更改字节序,然后使用这些值。

我没能找到的一件事是 best/most 常见的 处理字节顺序的方法 reading/writing 到 C++ 中的文件(没有联网)。那么我应该怎么做呢?为了帮助澄清,我要求最好的方法 read/write 16/32 位整数到大端系统和小端系统之间的文件。因为我关心不同系统之间的字节顺序,所以我也想要一个跨平台的解决方案。

最常见的方法是在将内存中的值写入文件之前通过 htons() 或 htonl() 传递内存中的值,并在读取数据后通过 ntohs() 或 ntohl() 传递读取的数据从文件中返回。 (htons()/ntohs() 处理 16 位值,htonl()/ntohl() 处理 32 位值)

当为大端 CPU 编译时,这些函数是无操作的(它们只是 return 你逐字传递给它们的值),所以这些值将被写入大端格式的文件。当为小端 CPU 编译时,这些函数端交换传入的值和 return 交换的版本,因此值将再次以大端格式写入文件。

这样文件中的值总是以大端格式存储,并且在传输时它们总是被转换to/from适当的(CPU-原生)格式to/from 记忆。这是最简单的方法(因为您不必编写或调试任何条件逻辑),也是最常见的方法(这些功能已在几乎所有平台上实现和可用)

在实践中,一个好习惯是避免使用二进制数据(在计算机之间交换数据),而更喜欢 text files and textual protocols to exchange data. You could use textual formats like JSON, YAML, XML, .... (or sometimes invent your own). There are many C++ libraries related to them, e.g. jsoncpp

文本数据确实更冗长(占用更多磁盘 space)并且解析速度稍慢(但磁盘 I/O 通常是瓶颈,而不是 CPU 时间 "wasted" 在像 JSON) 这样的解析或编码格式中,但更容易处理。

另请阅读 serialization. You'll find lots of libraries doing that (using some "common" well defined data format such as XDR or ASN1). Many file formats contain some header describing the concrete encoding. The elf(5) 格式就是一个很好的例子。

请注意,大多数时候数据比处理数据的软件更有价值(经济上)。因此,很好地记录数据在文件中的组织方式非常重要。

考虑对包含 JSON 的表格也使用 databases. Sometimes simply using sqlite 非常有效。

PS。如果没有实际案例,您的问题太宽泛,没有有意义的普遍答案。没有单一的最佳方法!

Basile,我同意没有通用的答案。

在我的世界里,嵌入式实时系统,使用文本表示是一种亵渎。文本表示和 JSON 比二进制表示至少慢 2 个数量级。对于网络来说可能没问题。但是,当您必须跨 DSP 和 GPP 每秒处理几千字节的数据(例如处理语音)时,情况就不同了。

有关此主题的更深入讨论,请查看 ZeroMQ 一书的 chapter 7