Java中的字节顺序转换——网络和主机顺序

3
这个话题很简单,但我可能有点混淆了。网络字节顺序是大端序。Java 默认使用大端序,例如 class 文件的情况。我的 Windows 机器使用的是 Intel 处理器,它是小端序的,而 Windows 本身也使用小端序。因此,如果我使用 java.nio.ByteBuffer.allocateDirect(),那么默认的字节顺序是小端序(因为操作系统和/或处理器),但是如果我想将这些数据发送到网络上,在从 ByteBuffer 读取数据时,我需要使用 ByteBuffer.order(ByteOrder.BIG_ENDIAN) 吗?另外,当从 Channel 读取数据到 ByteBuffer 时,我需要反过来做吗?在使用 java.io 包时,我几乎忽略了这个问题。
问题的另一部分也与在机器上工作有关。
  1. 我是否应该始终注意主机的字节顺序?因此,无论使用什么本地数据存储格式都可以在此机器环境中进行,但是在发送到网络时将数据转换为 BIG_ENDIAN。
  2. 就字节顺序而言,对于默认文件格式,例如在 Windows 上,它始终是小端序。但是,现在在具有大端序的 MAC 或 Linux 上使用相同的文件时,我应该使用字节顺序标记(BOM)保存它吗?

你最后一个问题没有意义。字符集与字节序无关。 - user207421
已编辑以消除UTF-8混淆。您能否请参见我对@TwoThe的评论。谢谢。 - Ashley
2个回答

8
这个话题相当简单,但我可能有点混淆了。网络字节序是大端序。Java默认也使用大端序(例如类文件)。在类文件的情况下,DataOutputStream、DataInputStream、ObjectInputStream、ObjectOutputStream、java.nio.*等都适用,我可能漏掉了某些内容。
如果使用java.nio.ByteBuffer.allocateDirect(),则默认的Endianness是Little-Endian(由于操作系统和/或处理器)。
不是。请参阅Javadoc,“新创建的ByteBuffer的顺序始终为big-endian”。
如果要将此数据发送到网络,请在读取ByteBuffer数据时使用ByteBuffer.order(ByteOrder.BIG_ENDIAN)吗?
已经是了。
另外,当从通道读取数据到ByteBuffer时,是否需要反转?
已经是了。
我几乎在使用java.io包时忽略了它。
DataInputStream和DataOutputStream使用big-endian。请参阅Javadoc。
我应该总是注意我的主机的Endianness吗?
在Java中不需要。
因此,在这台计算机的环境中,可以使用任何本地数据存储格式,但是在发送到网络时,把数据转换成BIG_ENDIAN。
这已经是默认的了。
就Endianness而言,对于默认文件格式,比如在Windows上,它总是小端序。
不是。见上面的回答。
然而,现在在MAC或使用Big-Endian的Linux上使用同一个文件,我是否应该使用字节顺序标记(BOM)保存它?
不需要,见上面的回答。

谢谢您的答复。我认为在Java中可以完全忽略字节序问题,因为默认情况下它始终为BIG_ENDIAN。但是我曾经在某个地方读到,对于延迟敏感的应用程序,意识到字节序优势显而易见,如果不关注可能会浪费一个交换操作。然而,看起来我几乎不必担心它。再次感谢。 - Ashley
1
很明显,当必须采取行动时,Java在内部使用平台字节序,例如将寄存器相加,但是无法从Java程序内部观察到这一点。 - user207421

-2

您需要始终发送相同的字节序。选择哪种字节序应基于主机上可以处理的速度。如果您的代码主要在基于x86的计算机上使用,则建议在所有地方都使用小端字节序。JVM 在内部也会执行相同操作(在此操作系统上)。


感谢您的回答。因此,JVM除了类编写之外,将使用与默认操作系统相同的字节序,因此我现在明白了网络字节顺序应始终在发送/接收时首先转换为大端序。我的困惑仍然存在,即java.net和/或java.io和/或java.nio API是否会自行执行hton(主机到网络)和ntoh(网络到主机)?问题的另一部分仍然存在,“如果我使用USB驱动器将Windows文件(小端)复制到Apple MAC(大端)上会怎样?”在文件/标头中如何确定其字节序? - Ashley
我想问的另一个问题是:如果默认的JVM使用Little-Endian(与主机相同),那么我是否需要将我的InputStream read()或ByteBuffer读取顺序反转为Big-Endian?根据我的经验,我从未遇到过必须这样做的情况,因为我总是在Windows世界中,所以假设Java自己会处理它。请评论。 - Ashley
1
十分误导的回答。Java对此进行了隐藏,您不需要采取任何措施。-1 - user207421
@EJP,我也一直在查看这个,你上面的回答看起来更符合Java文档。 - Ashley

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