java - 从二进制文件中读取 2 的补码中的 2 字节整数为整数
java - reading 2 byte integer in 2's complement from binary file into integer
我正在尝试解析包含值的二进制文件。在规范中,它表示每个值 以 2 的补码格式 表示为 2 字节整数。
我正在将文件读入一个名为 'data':
的字节数组
int i = (data[i] & 0xff) | (short) (data[i+1] << 8);
这些值看起来不错,但是当我尝试将它们写回文件时:
byte a = (byte)((tempInt >> 8) & 0xff);
byte b = (byte)(tempInt & 0xff);
'tempInt' 是 int 中的值。
当我读入我写的文件时,并不是所有的值都相同。
其中一些但不是全部。
我是不是漏掉了什么?
更新:
我绘制了比较值。
上半部分是我从文件中读取的值。
下半部分是我从文件中读取的值,然后写入一个新文件,然后再次读取。
我认为这些图表看起来太相似以至于完全错误。
更新#2:
我从输入文件中读取的字节数:
0, 0, 59, 36, 40, 36, 23, 36, 54, 36, 54, 36, 41, 36, 46, 36, 50, 36, 52, 36, 79, 36, 79, 36, 66, 36, 65, 36, 58, 36, 58, 36, 58, 36, 45, 36, 51, 36, 65, 36, 65, 36, 76, 36, 78, 36, 69, 36, 54, 36, 68, 36, 86, 36, 85, 36, 81, 36, 81, 36, 80, 36, 84, 36, 84, 36, 80, 36, 82, 36, 85, 36, 81, 36, 80, 36, 75, 36, 75, 36, 79, 36, 91, 36, 83, 36, 64, 36, 71, 36, 79, 36, 56, 36, 38, 36, 47, 36, 51, 36, 41, 36, 48, 36, 63, 36, 56, 36, 50, 36, 57, 36, 67, 36, 78, 36, 81, 36, 67, 36, 81, 36, 81, 36, 82, 36, 69, 36, 66, 36, 66, 36, 54, 36, 39, 36, 78, 36, 78, 36, 78, 36, 62, 36, 57, 36, 73, 36, 75, 36, 69, 36, 76, 36, 81, 36, 74, 36
转换后的整数:
0, 9275, 9256, 9239, 9270, 9270, 9257, 9262, 9266, 9268, 9295, 9295, 9282, 9281, 9274, 9274, 9274, 9261, 9267, 9281, 9281, 9292, 9294, 9285, 9270, 9284, 9302, 9301, 9297, 9297, 9296, 9300, 9300, 9296, 9298, 9301, 9297, 9296, 9291, 9291, 9295, 9307, 9299, 9280, 9287, 9295, 9272, 9254, 9263, 9267, 9257, 9264, 9279, 9272, 9266, 9273, 9283, 9294, 9297, 9283, 9297, 9297, 9298, 9285, 9282, 9282, 9270, 9255, 9294, 9294, 9294, 9278, 9273, 9289, 9291, 9285, 9292, 9297, 9290
我从上面的值写入的文件中读取的字节数:
32, 0, 0, 36, 59, 36, 40, 36, 23, 36, 54, 36, 54, 36, 41, 36, 46, 36, 50, 36, 52, 36, 79, 36, 79, 36, 66, 36, 65, 36, 58, 36, 58, 36, 58, 36, 45, 36, 51, 36, 65, 36, 65, 36, 76, 36, 78, 36, 69, 36, 54, 36, 68, 36, 86, 36, 85, 36, 81, 36, 81, 36, 80, 36, 84, 36, 84, 36, 80, 36, 82, 36, 85, 36, 81, 36, 80, 36, 75, 36, 75, 36, 79, 36, 91, 36, 83, 36, 64, 36, 71, 36, 79, 36, 56, 36, 38, 36, 47, 36, 51, 36, 41, 36, 48, 36, 63, 36, 56, 36, 50, 36, 57, 36, 67, 36, 78, 36, 81, 36, 67, 36, 81, 36, 81, 36, 82, 36, 69, 36, 66, 36, 66, 36, 54, 36, 39, 36, 78, 36, 78, 36, 78, 36, 62, 36, 57, 36, 73, 36, 75, 36, 69, 36, 76, 36, 81, 36
转换后的整数:
32, 9216, 9275, 9256, 9239, 9270, 9270, 9257, 9262, 9266, 9268, 9295, 9295, 9282, 9281, 9274, 9274, 9274, 9261, 9267, 9281, 9281, 9292, 9294, 9285, 9270, 9284, 9302, 9301, 9297, 9297, 9296, 9300, 9300, 9296, 9298, 9301, 9297, 9296, 9291, 9291, 9295, 9307, 9299, 9280, 9287, 9295, 9272, 9254, 9263, 9267, 9257, 9264, 9279, 9272, 9266, 9273, 9283, 9294, 9297, 9283, 9297, 9297, 9298, 9285, 9282, 9282, 9270, 9255, 9294, 9294, 9294, 9278, 9273, 9289, 9291, 9285, 9292, 9297
更新#3:
好的,所以我制作了一个小版本的程序,我只是从文件中读取字节,将它们转换为整数,将它们转换回字节并将它们写入文件。没有整个数据格式。
它确实有效。所以问题出在算法上,而不是字节到 int(再回到字节)的转换。
我会回去检查算法。
感谢您的帮助:)
试试这个:
int i = ((short)data[i] & 0xff) | ((short)data[i+1] << 8);
由于 data
是 byte
的数组,因此值 data[i+1] << 8
超过 8 位,产生零值。我只是在向左移动之前将值 data[i+1]
转换为 shrt
。
是 - 您正在 阅读 little-endian 格式(第一个值最不重要),但您正在 写作 它们采用 big-endian 格式(第一个值最重要),假设您正在编写 a
然后 b
.
假设文件是 little-endian:
byte a = (byte)(tempInt & 0xff);
byte b = (byte)((tempInt >> 8) & 0xff);
我正在尝试解析包含值的二进制文件。在规范中,它表示每个值 以 2 的补码格式 表示为 2 字节整数。 我正在将文件读入一个名为 'data':
的字节数组int i = (data[i] & 0xff) | (short) (data[i+1] << 8);
这些值看起来不错,但是当我尝试将它们写回文件时:
byte a = (byte)((tempInt >> 8) & 0xff);
byte b = (byte)(tempInt & 0xff);
'tempInt' 是 int 中的值。
当我读入我写的文件时,并不是所有的值都相同。 其中一些但不是全部。
我是不是漏掉了什么?
更新:
我绘制了比较值。
上半部分是我从文件中读取的值。
下半部分是我从文件中读取的值,然后写入一个新文件,然后再次读取。
更新#2: 我从输入文件中读取的字节数:
0, 0, 59, 36, 40, 36, 23, 36, 54, 36, 54, 36, 41, 36, 46, 36, 50, 36, 52, 36, 79, 36, 79, 36, 66, 36, 65, 36, 58, 36, 58, 36, 58, 36, 45, 36, 51, 36, 65, 36, 65, 36, 76, 36, 78, 36, 69, 36, 54, 36, 68, 36, 86, 36, 85, 36, 81, 36, 81, 36, 80, 36, 84, 36, 84, 36, 80, 36, 82, 36, 85, 36, 81, 36, 80, 36, 75, 36, 75, 36, 79, 36, 91, 36, 83, 36, 64, 36, 71, 36, 79, 36, 56, 36, 38, 36, 47, 36, 51, 36, 41, 36, 48, 36, 63, 36, 56, 36, 50, 36, 57, 36, 67, 36, 78, 36, 81, 36, 67, 36, 81, 36, 81, 36, 82, 36, 69, 36, 66, 36, 66, 36, 54, 36, 39, 36, 78, 36, 78, 36, 78, 36, 62, 36, 57, 36, 73, 36, 75, 36, 69, 36, 76, 36, 81, 36, 74, 36
转换后的整数:
0, 9275, 9256, 9239, 9270, 9270, 9257, 9262, 9266, 9268, 9295, 9295, 9282, 9281, 9274, 9274, 9274, 9261, 9267, 9281, 9281, 9292, 9294, 9285, 9270, 9284, 9302, 9301, 9297, 9297, 9296, 9300, 9300, 9296, 9298, 9301, 9297, 9296, 9291, 9291, 9295, 9307, 9299, 9280, 9287, 9295, 9272, 9254, 9263, 9267, 9257, 9264, 9279, 9272, 9266, 9273, 9283, 9294, 9297, 9283, 9297, 9297, 9298, 9285, 9282, 9282, 9270, 9255, 9294, 9294, 9294, 9278, 9273, 9289, 9291, 9285, 9292, 9297, 9290
我从上面的值写入的文件中读取的字节数:
32, 0, 0, 36, 59, 36, 40, 36, 23, 36, 54, 36, 54, 36, 41, 36, 46, 36, 50, 36, 52, 36, 79, 36, 79, 36, 66, 36, 65, 36, 58, 36, 58, 36, 58, 36, 45, 36, 51, 36, 65, 36, 65, 36, 76, 36, 78, 36, 69, 36, 54, 36, 68, 36, 86, 36, 85, 36, 81, 36, 81, 36, 80, 36, 84, 36, 84, 36, 80, 36, 82, 36, 85, 36, 81, 36, 80, 36, 75, 36, 75, 36, 79, 36, 91, 36, 83, 36, 64, 36, 71, 36, 79, 36, 56, 36, 38, 36, 47, 36, 51, 36, 41, 36, 48, 36, 63, 36, 56, 36, 50, 36, 57, 36, 67, 36, 78, 36, 81, 36, 67, 36, 81, 36, 81, 36, 82, 36, 69, 36, 66, 36, 66, 36, 54, 36, 39, 36, 78, 36, 78, 36, 78, 36, 62, 36, 57, 36, 73, 36, 75, 36, 69, 36, 76, 36, 81, 36
转换后的整数:
32, 9216, 9275, 9256, 9239, 9270, 9270, 9257, 9262, 9266, 9268, 9295, 9295, 9282, 9281, 9274, 9274, 9274, 9261, 9267, 9281, 9281, 9292, 9294, 9285, 9270, 9284, 9302, 9301, 9297, 9297, 9296, 9300, 9300, 9296, 9298, 9301, 9297, 9296, 9291, 9291, 9295, 9307, 9299, 9280, 9287, 9295, 9272, 9254, 9263, 9267, 9257, 9264, 9279, 9272, 9266, 9273, 9283, 9294, 9297, 9283, 9297, 9297, 9298, 9285, 9282, 9282, 9270, 9255, 9294, 9294, 9294, 9278, 9273, 9289, 9291, 9285, 9292, 9297
更新#3: 好的,所以我制作了一个小版本的程序,我只是从文件中读取字节,将它们转换为整数,将它们转换回字节并将它们写入文件。没有整个数据格式。 它确实有效。所以问题出在算法上,而不是字节到 int(再回到字节)的转换。 我会回去检查算法。 感谢您的帮助:)
试试这个:
int i = ((short)data[i] & 0xff) | ((short)data[i+1] << 8);
由于 data
是 byte
的数组,因此值 data[i+1] << 8
超过 8 位,产生零值。我只是在向左移动之前将值 data[i+1]
转换为 shrt
。
是 - 您正在 阅读 little-endian 格式(第一个值最不重要),但您正在 写作 它们采用 big-endian 格式(第一个值最重要),假设您正在编写 a
然后 b
.
假设文件是 little-endian:
byte a = (byte)(tempInt & 0xff);
byte b = (byte)((tempInt >> 8) & 0xff);