Java字节数组包含负数

时间:2012-03-07 21:32:16

标签: java file-io

我正在将文件读入块中的字节数组,并通过网络服务器通过POST请求将其发送到网络服务器。这并不复杂,我在使用这个完全相同的代码之前已经完成了。这一次,我注意到我的图像在到达服务器时看起来很奇怪,所以我决定查看正在发送的字节数组和正在接收的字节数据以确保它是相同的。不是。在java发送端,字节数组包含负数。在C#接收方,没有负数。

接收方的前15个字节(C#)

137
80
78
71
13
10
26
10
0
0
0
13
73
72
68

那些相同的字节,但在发送方(java)

-119
80
78
71
13
10
26
10
0
0
0
13
73
72
68

所有非负数都相同,-119不是唯一的负数,它们全部结束。我注意到-119和137分别是256,并想知道这是否与它有关。

我用来读取图像的代码(java)

public static byte[] readPart(String fileName, long offset, int length) throws FileNotFoundException, Exception
{
    byte[] data = new byte[length];
    File file = new File(fileName);
    InputStream is = new FileInputStream(file);
    is.skip(offset);
    is.read(data,0,data.length);
    is.close();
    return data;
}

我用来编写数据的代码(c#)

    private void writeFile(string fileName, Stream contents)
    {
        using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
        {
            int bufferLen = 65000;
            byte[] buffer = new byte[bufferLen];
            int count = 0;
            while ((count = contents.Read(buffer, 0, bufferLen)) > 0)
            {
                fs.Write(buffer, 0, count);
            }
            fs.Close();
        }
        contents.Close();
    }

我不知道这是否总会发生,而我之前从未注意过它,或者它是否决定出现可怕的错误。我所知道的是,此代码之前的代码非常相似,而且现在无法正常工作。

如果有人有任何建议或解释,我会非常感激。

编辑: 我的图像看起来很奇怪的原因是我如何调用readPart方法。

byte[] data = FileUtilities.readPart(fileName,counter,maxFileSize);//counter is the current chunk number

我该怎么称呼它

byte[] data = FileUtilities.readPart(fileName,counter*maxFileSize,maxFileSize);//the current chunk * cuhnksize for the offset...

谢谢大家,我现在明显不那么困惑了。)

5 个答案:

答案 0 :(得分:38)

在Java中,byte是一个有符号的值(使用two's complement来编码负值),所以大多数人都会意外地看到它是正确的。

要将byte转换为无符号int值,请使用b & 0xff

答案 1 :(得分:30)

Java没有无符号字节;所有字节都被视为已签名。就是这样。

真正重要的是你如何认为字节,因为你几乎不需要对字节进行比较。唯一显着的区别是,正如您所发现的那样,它们以签名的形式打印出来。

如果您愿意,可以使用例如Guava的UnsignedBytes实用程序将Java字节视为无符号,但实际上没有太大的区别。

答案 2 :(得分:12)

作为进一步说明,假设您将137作为无符号字节。这表示为:

1000 1001

这个二进制值,当用带符号的二进制补码数表示时,结果为-119。 (-128 + 9

128以上的任何无符号字节值都会受到差异的影响,因为最左边的位通过二进制补码方案以这种方式使用。

答案 3 :(得分:3)

也许它与Java的字节被签名(范围-128到127)这一事实有关,而C#是无符号的(0到255):)。二进制信息是相同的,它的解释方式不同。

答案 4 :(得分:0)

字节的范围是-128到127,因此,如果您尝试分配一个字节128,则它将循环循环,结果将是-128。

this.setState(state => ({
   elements: [...state.elements, ...data]
}));