java字节输入流为什么是int_字节输入流的read()方法读取中文汉字得到的int值是怎么得到的?...

为什么相减都是256?因为它们是对同样的东西的不同表达。

我们一会儿再讨论为什么“我”是这几个数。我们先讨论为什么打印的时候它们有正有负。

首先,java的byte类型取值范围是-128到127,而不是unsigned的0到255。这种解释方式决定了byte本身就是可以有负数的。byte的最高位会被认为是符号位,因此当最高位是1时它会被认为是负数。所以,很自然地,在你使用byte类型的变量做输出时,标准输出流会显示一个负数。这并没有什么好奇怪的。

接下来我们再来看OutputStream的行为。根据API文档,OutputStream.write()的原型是

public abstract void write(int b) throws IOException

我们可以发现,参数类型是int而不是byte。这里会做隐式类型提升,byte会被扩充为int,而多出来的24位会根据符号位自动补全。这里由于是负数,所以填的全是1。然而根据文档的描述,Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.

OutputStream会把高24位丢弃,所以并没有改变byte的内容。现在我们知道了往磁盘上写的只有低8位。自然,这低8位还是一个负数。

问题的关键出现在InputStream。我们来看InputStream.read()的函数原型

public abstract int read() throws IOException

它返回的居然是一个int!并且根据文档描述,Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

我们发现,这个int的有效范围是0到255,无效时返回-1。

所以,很简单。那8位还是那8位,只是由于InputStream把它当做一个无符号数来理解了,并且相应的返回了正的东西,这才导致了标准输入流输出正数。

不信你可以根据补码运算规则自己算一下。

至于为什么是这三个字节,根据String.getBytes()的描述,默认会使用平台字符集进行编码。也就是说,你的操作系统的语言和字符集会影响这个函数的行为。当然,你也可以手动指定想要使用的字符集和编码方式。

关于字符集和编码的简单介绍可以看我以前的文章关于字符集和编码​www.bilibili.com34190794919a6840b7163d1b7a68f07a.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值