在java中读取二进制文件时将little endian转换为big endian

时间:2013-02-12 00:04:51

标签: java windows

现在我有一个程序,我必须从二进制文件中读取数字。数字是小端的,我必须转换为大端的java代码。我没有得到任何东西。所以任何人都可以发布我怎么能做它。请你。谢谢。

5 个答案:

答案 0 :(得分:3)

使用nio和ByteBuffer读取它,您将完成.order(ByteOrder.LITTLE_ENDIAN)

Javadoc

答案 1 :(得分:2)

答案 2 :(得分:1)

Apache commons有一个Little Endian InputStream,多年来

答案 3 :(得分:1)

到目前为止答案很好,但我不得不承认,这些天我在.NET上花的时间比在java中花的时间多。

但是,我确实觉得除了其他人在这里提出的答案之外,实际上值得发布一个答案来描述小端和大端之间的区别。

通常,当我看到这样的问题时,人们并没有意识到这实际上是一项非常简单的任务,只需要花费大约5分钟来实施。

Endiness就是指给定数字的字节实际存储在二进制文件中的顺序。

让我们举一个16位“短整数”的简单例子(可以受此影响的最小尺寸)

如果你停止以“字节”来考虑这个问题,那么你会立即看到16位实际上等于2个字节。

现在,如果你开始将这些字节分解为最低和最高顺序,你实际上得到一个低位字节和一个高位字节。

如果我们想象,我们有值511,由2个字节的

表示
1

256

为什么?

数字中的位数是2的幂,如果你从右到左遍历2的幂,你得到:

128  64  32  16  8  4  2  1

如果将所有这些列添加到一起,您将看到可以获得的最大值为255

当所有位都满了,你必须进入下一位,所以为了得到511我们必须有

256  128  64  32  16  8  4  2  1

通过扩展分成字节实际上变为

1 | 128  64  32  16  8  4  2  1

与|表示两个8位字节之间的分割的字符。

或以图形形式

-------------
|  1  | 255 |
-------------

我不会太深入二进制,否则我最终会偏离主题,但是有很多不错的参考资料,例如维基百科上的这个:

http://en.wikipedia.org/wiki/Binary_number

回到我们的字节...

当您将这些字节写入文件时,可以写入1然后写入255,也可以写入255然后写入1

如果你先写1,那就叫做“Big Endian”,因为你先写两个字节的最大(最高)值。

如果先写入255,那么先写下两个值中最小的(较低的),这样就得到名字“Little Endian”

你如何从一个转换为另一个?

这很简单,如果值作为“Little Endian”值存储在文件中,那么您基本上需要执行以下操作:

Read One Byte into A
Read One Byte into B
Make 16 bit Result = (B << 8) + A

如果它作为“Big Endian”值存储在文件中

Read One Byte into A
Read One Byte into B
Make 16 bit Result = (A << 8) + B

其他数字类型同样简单,采用常规的32位整数...

将其分解为等于4,8位字节

-----------------
| 4 | 3 | 2 | 1 |
-----------------

1为最低,4为最高。

“Little Endian”中,字节将存储在文件中,如下所示:

-----------------
| 1 | 2 | 3 | 4 |
-----------------

将其读出来:

Read One Byte into A
Read One Byte into B
Read One Byte into C
Read One Byte into D
Make 32 bit Result = (D << 24) + (C << 16) + (B << 8) + A

并在“Big Endian”

-----------------
| 4 | 3 | 2 | 1 |
-----------------

将其读出来:

Read One Byte into A
Read One Byte into B
Read One Byte into C
Read One Byte into D
Make 32 bit Result = (A << 24) + (B << 16) + (C << 8) + D

所以你看,只要你知道如何读取单个字节(在任何语言中)你真的不需要任何额外的例程或库调用,只需要一点点左移......

和那些好奇的人

将32位整数写为

“Little Endian”

Make R = 32 bit integer to store
Make 8 bit Value A = R AND 255
Make 8 bit Value B = (R >> 8) AND 255
Make 8 bit Value C = (R >> 16) AND 255
Make 8 bit Value D = (R >> 24) AND 255
Write A as byte to file
Write B as byte to file
Write C as byte to file
Write D as byte to file

“Big Endian”

Make R = 32 bit integer to store
Make 8 bit Value A = R AND 255
Make 8 bit Value B = (R >> 8) AND 255
Make 8 bit Value C = (R >> 16) AND 255
Make 8 bit Value D = (R >> 24) AND 255
Write D as byte to file
Write C as byte to file
Write B as byte to file
Write A as byte to file

答案 4 :(得分:0)

您可能在代码中做错了什么。我最近写了一篇关于如何读写二进制文件以及如何转换字节序的博客文章。在将数据读入字节

后需要调用flip()
FileChannel fc = (FileChannel) Files.newByteChannel(Paths.get(filename), StandardOpenOption.READ);
ByteBuffer byteBuffer = ByteBuffer.allocate((int)fc.size());
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
fc.read(byteBuffer);
byteBuffer.flip();

http://pulasthisupun.blogspot.com/2016/06/reading-and-writing-binary-files-in.html