1

我正在尝试为 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;
    }

这给出了正确的输出

4

2 回答 2

10

在 java 中字节是有符号的,所以你在 java 字节中的 -64 是二进制等效于 c# 字节中的 192(192 == 256 - 64)。

问题很可能出在byteArrayToInt()您假设它在转换期间未签名的地方。

一个简单的

 `b & 0x000000FF`

在这种情况下可能会有所帮助。

于 2012-04-09T07:53:40.350 回答
2

Java 的字节对象按照 soulcheck 所写的方式进行签名。无符号 8 位整数上 192 的二进制值将是11000000.

如果您正在使用带符号格式读取此值,则前导 1 将表示负数。这意味着11000000变为negative 01000000,即 -64。

于 2012-04-09T07:56:43.447 回答