有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

文件io Java字节数组包含负数

我将一个文件分块读入字节数组,并通过POST请求通过网络发送到Web服务器。这并不复杂,我在使用完全相同的代码之前就做过。这一次,我注意到我的图像在到达服务器时看起来非常奇怪,所以我决定查看发送的字节数组和接收的字节数组,以确保它们是相同的。不是。在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) 个答案

  1. # 1 楼答案

    也许这与以下事实有关:Java的字节是有符号的(范围为-128到127),而C#的字节是无符号的(0到255):)。信息在二进制中是相同的,只是解释不同而已

  2. # 2 楼答案

    在Java中,byte是一个有符号的值(使用two's complement对负值进行编码),因此,如果大多数人没有预料到,那么您认为它是正确的

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

  3. # 3 楼答案

    字节的范围是从-128到127,所以如果你尝试分配一个字节128,它将循环,结果将是-128

    System.out.println("Max val = " + Byte.MAX_VALUE);   //prints: Max val = 127
    System.out.println("Min val = " + Byte.MIN_VALUE);   //prints: Min val = -128
    
    System.out.println("(byte)137 = " + (byte)137);      //prints: (byte)137 = -119
    System.out.println("(byte)128 = " + (byte)128);      //prints: (byte)128 = -128
    System.out.println("(byte)-129 = " + (byte)-129);    //prints: (byte)-129 = 127
    
  4. # 4 楼答案

    作为进一步的解释,假设137是一个无符号字节。具体表现为:

    1000 1001
    

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

    任何超过128的无符号字节值都会受到差异的影响,因为最左边的位是以这种方式被两个补码方案使用的

  5. # 5 楼答案

    Java没有无符号字节;所有字节都被视为有符号字节。就这些

    真正重要的是你如何看待字节,因为你很少真正需要对字节进行比较。唯一显著的区别是,正如你所发现的,它们是以签名的形式打印出来的

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