我正在尝试为C#中的函数编写Java等价物。代码如下。
在C#中:
byte[] a = new byte[sizeof(Int32)];
readBytes(fStream, a, 0, sizeof(Int32)); //fstream is System.IO.Filestream
int answer = BitConverter.ToInt32(a, 0);
在Java中:
InputStream fstream = new FileInputStream(fileName);
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
byte[] a = new byte[4];
readBytes(in, a, 0, 4);
int answer = byteArrayToInt(a);
Java和C#:
int readBytes(Stream stream, byte[] storageBuffer, int offset, int requiredCount)
{
int totalBytesRead = 0;
while (totalBytesRead < requiredCount)
{
int bytesRead = stream.Read(
storageBuffer,
offset + totalBytesRead,
requiredCount - totalBytesRead);
if (bytesRead == 0)
{
break; // while
}
totalBytesRead += bytesRead;
}
return totalBytesRead;
}
输出:
In C#: answer = 192 (Correct)
In JAVA: answer = -1073741824
两者有所不同。我正在从文件输入流中读取,该文件输入流被编码并解析前四个字节。 C#代码似乎产生192这是正确答案,而Java产生-1073741824,这是错误的答案。为什么以及如何?
修改
这是我的byteArrayToInt
public static int byteArrayToInt(byte[] b, int offset) {
int value = 0;
for (int i = 0; i < 4; i++) {
int shift = (4 - 1 - i) * 8;
value += (b[i + offset] & 0x000000FF) << shift;
}
return value;
}
解 byteArrayToInt的正确解决方案
public static int byteArrayToInt(byte[] b)
{
long value = 0;
for (int i = 0; i < b.length; i++)
{
value += (b[i] & 0xff) << (8 * i);
}
return (int) value;
}
这给出了正确的输出
答案 0 :(得分:10)
在java字节中是有符号的,因此java字节中的-64二进制等效于c#byte中的192(192 == 256 - 64)。
问题是byteArrayToInt()
中的probaby,您认为它在转换过程中是无符号的。
一个简单的
`b & 0x000000FF`
在这种情况下,可能会有所帮助。
答案 1 :(得分:2)
Java的字节对象是在soulcheck写的时候签名的。无符号8位整数的192的二进制值为11000000
。
如果您使用签名格式读取此值,则前导1将表示否定。这意味着11000000
变为negative 01000000
,即-64。