编程语言中的字节序问题

6
好的,“字节序”这个主题对我来说一直有点困惑,但我从未遇到需要考虑我使用的二进制读写器的默认行为的问题。我现在正在用C#编写PNG解码器。PNG文件格式规范指出所有数字都以大端记法存储(我觉得非常自然)。然而,当我注意到.NET的BinaryReader/Writer使用小端记法时,我非常惊讶。更让我困惑的是,Java的二进制IO使用大端记法(我不是Java程序员,所以可能我错了)。因此,我开始思考以下问题:
1- 为什么事情是这样的?我的意思是基类库的默认行为。 2- 为什么在使用.NET的System.IO时没有选择首选符号的方法?
我目前正在使用Jon Skeet's MiscUtil,它工作得很好(谢谢,人 =))。但是,在基类库中看到这个功能会很酷。
3个回答

10

这是因为代码旨在在最重要的平台上尽可能高效地运行。C#/.NET来自微软,主要在x86平台上运行。x86是小端序,因此将库设计为小端序是有意义的。Java由Sun公司开发,而Sun SPARC是大端序,因此Java标准采用了大端序。


紧凑型和微型框架怎么样?尽管我同意这可能是一个因素,但.NET的本质有点平台无关。 - n535
2
Java被设计成平台无关的,这就是为什么他们选择了更自然的排序方式。.NET的平台独立性是其次要的,主要是为了规范Windows平台上的各种语言,并引入新的语言特性,如垃圾回收等。MS / Intel世界在这方面往往是目光短浅的,因此大多数Windows程序员阅读的文件都是小端序的。小端序是/曾经是Intel芯片上的首选排序方式。 - PSpeed
+1 嗯,当然这很有道理,但仍然无法解释为什么没有选择。在BCL中以非常高效的方式实现这一点是值得的。 - n535
同意。在Java中,选择也不是100%直截了当的...我自己读过很多小端文件。 - PSpeed
@PSpeed 更自然地是指对谁?“mov 42 register”你会用什么自然的方式来检查它... - Jay
显示剩余3条评论

2

BCL 包含在 System.BitConverter 静态类中的内容,允许您处理系统字节序。由于这个原因,BitConverter 中的所有方法基本上都是平台无关的。

此外,System.Net.IPAddress.NetworkToHostOrder 方法允许您从大端序到小端序或者从小端序到大端序进行转换。


除了IsLittleEndian属性之外还有什么?System.Net.IPAddress.NetworkToHostOrder虽然与实际问题相距甚远。 - n535
我不确定我理解你的问题。我经常使用BinaryReader和BinaryWriter读写二进制文件,如果字节顺序不是我想要的,我只需要交换字节(通常使用NetworkToHostOrder)。这有什么大不了的? - Robert Harvey
其实,并不存在“问题”。事实上,你可以在.NET中使用PNG,所以我认为.NET Core开发人员也没有问题。但我也担心,在读取时即时正确解释字节可能更有效率,而不需要进一步进行反转。当然,自己实现并不难,但我认为这些东西应该在框架中提供,因为它们非常普遍(这解释了 MiscUtil 等工具存在的原因)。我真正想弄清楚的唯一一件事就是,是否存在某些严重的理由,导致我们在.NET中没有这样的功能。 - n535
1
NetworkToHostOrder非常快。我必须相信,从文件中读取字节所需的时间至少比翻转字节所需的时间长两个数量级。 - Robert Harvey

1
我想这归结于无论你在哪个平台上,都能够处理两者。Preon试图通过允许您使用注释声明性地定义内存数据表示和编码表示之间的映射来隐藏某些复杂性。
因此,如果这是您的数据结构的一部分:
public Image {
    int width;
    int height;
}

那么定义到自然大端表示的映射就很容易,像这样:

public Image {
    @BoundNumber int width;
    @BoundNumber int height;
}

然而,如果表示是小端的,那么你可以这样做:
public Image {
    @BoundNumber(byteOrder=LittleEndian) int width;
    @BoundNumber(byteOrder=LittleEndian) int height;
}

在这两种情况下,为此数据结构创建编解码器是相同的:

Codec<Image> codec = Codecs.create(Image.class);

我知道有些人正在谈论将其移植到.NET上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接