Java字节数组包含负数

Java字节数组包含负数,java,file-io,Java,File Io,我将一个文件分块读入字节数组,并通过POST请求通过网络发送到Web服务器。这并不复杂,我在使用完全相同的代码之前就做过。这一次,我注意到我的图像在到达服务器时看起来非常奇怪,所以我决定查看发送的字节数组和接收的字节数组,以确保它们是相同的。不是。在java发送端,字节数组包含负数。在C#接收方,没有负数 接收端的前15个字节(C#) 相同的字节,但在发送端(java) 所有的非负数都是一样的,-119不是唯一的负数,它们都结束了。我确实注意到-119和137相距256,我想知道这是否与此有关

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

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

相同的字节,但在发送端(java)

所有的非负数都是一样的,-119不是唯一的负数,它们都结束了。我确实注意到-119和137相距256,我想知道这是否与此有关

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

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

我不知道这是否是经常发生的事情,我只是以前从来没有注意到,或者这是否是决定出严重错误的事情。我所知道的是,这段代码以前在非常类似的情况下工作过,但现在不起作用了

如果有人有任何建议或解释,我将不胜感激

编辑: 我的图像看起来很奇怪的原因是我调用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...

谢谢大家,我现在不那么困惑了:)

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

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


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

在Java中,
字节是有符号的值(用于编码负值),因此,如果大多数人没有预料到,您所看到的是正确的


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

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

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

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


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

字节的范围是从-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

在使用data[i]=(byte)Math.abs((int)data[i])发送之前,尝试将所有字节设置为正;这不起作用,它告诉我图像在那一点上已损坏。它只是整个文件的第一个字节,还是每个块的第一个字节?Java的
字节
是有符号的,因此不可能将137存储在
字节
中。也许你的问题来自于此?有符号和无符号字节应该与图像的奇怪显示无关。你确定整个图像都发送过来了吗?将结果图像写入文件,并比较字节数。@CookieofFault比发送整个图像的字节数多。。。我刚发现。当我的最大块大小足够大,可以发送整个文件时,就可以了。如果不是,例如1024,我总共发送135168字节,其中我只想发送134762。135168也是保存的文件大小,所以我怀疑奇怪的图像就是这样的,在C#中,
byte
是无符号的,
sbyte
是有符号的。从Java 1.8开始,
byte
类获得了一些静态方法来获取字节的无符号值:*一个用于int
byte.toUnsignedInt(byte)
,*一个长
Byte.toUnsignedLong(Byte)
我可以确认它是有效的,并且可以理解它。在-25的基础上再加上+256(在我的例子中是0xE7)实际上也可以。尽管如此,我还是不能完全理解这里的实际问题。您能再解释一下位移位的作用吗?
(byte)0xE7+256
将带符号的字节转换为
int
(仍然为-25),然后添加
(int)256
。要完全理解正在发生的事情,您必须首先理解,一切都只是一个位模式,您通过以特定方式定义数学运算来编码真实事物,从而赋予这些位以意义。有了这些知识,您可以阅读链接文章来理解位模式的含义。下一步是理解Java的类型扩展规则:最后,我能够在调试时验证字节是否正确。我有-16,这反过来是240作为ubyte(240-256)=-16,为什么Java有负数是byte?它们有什么用处?chiperortiz我想这只是为了匹配其所有其他基本二进制类型的约定。我希望他们已经启用了有符号和无符号类型,但现在,我认为这将是一个重大变化。在处理Java中可能会自动向上转换为更大类型的“负值”时,您只需小心,因为它将对它们进行符号扩展,而不是以零作为前缀,如果您没有预料到的话,这可能会导致错误。
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...
1000 1001
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