文档章节

为什么InputStream.read()读取一个byte确返回一个int呢?

BlackJoker
 BlackJoker
发布于 2015/10/13 13:24
字数 406
阅读 51
收藏 0

问题1:为什么InputStream.read()读取一个byte却返回一个int呢?

InputStream.read()返回一个unsigned byte [0 - 255],而java里面没有这个类型,所以用int接收。

byte的范围是[-128,127],所以如果read()返回的数在[128,255]的范围内时,则表示负数,即

 

(byte)128=-128

 

(byte)129=-127

 

(byte)255=-1

 

所以如果read()返回的是byte的话,那就会有负数。而"返回-1意味着结束",这个信息量用byte是无法表达的,所以必须用int。

 

问题2:如何把一个整数(int)正确保存到一个byte数组,并从里面正确的读出来?

先看代码再解释:

public static int readInt(byte[] readBuffer, int offset) {
		int i = offset;
		//readBuffer[i]范围是[-128,127],转整形时必须是[0,255]
		int ch1 = readBuffer[i++] & 255;
		int ch2 = readBuffer[i++] & 255;
		int ch3 = readBuffer[i++] & 255;
		int ch4 = readBuffer[i++] & 255;
		return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
	}

	public static void writeInt(int v, byte[] writeBuffer, int offset) {
		int i = offset;
		//这里面会存在负数
		writeBuffer[i++] = (byte) (v >>> 24);
		writeBuffer[i++] = (byte) (v >>> 16);
		writeBuffer[i++] = (byte) (v >>> 8);
		writeBuffer[i++] = (byte) (v >>> 0);
	}

 

 

对于writeInt:v无符号右移>>>肯定是正数,即[0,255],用byte强转型后就可能负数[-128,127]。

 

对于readInt:readBuffer[i++]是有负数的,必须转成无符号整形,即&255变成[0,255]范围之后才可以用于组装int。 

 

延伸3:

 OutputStream.write(int b):相当与write(b&255),

如果你write(-2),因为-2&255=254,那么相应的r = InputStream.read()返回的是254,需要(int) (byte) r才能获取你想要的值((byte)254=-2)

 

结论:可以认为OutputStream和InputStream里面都是unsigned byte。

 

 

© 著作权归作者所有

共有 人打赏支持
BlackJoker
粉丝 1
博文 17
码字总数 9270
作品 0
深圳
高级程序员
java InputStream读取数据问题

转载地址:点击打开链接 首先请查看一下JavaAPI,可以看到InputStream读取流有三个方法,分别为read(),read(byte[] b),read(byte[] b, int off, int len)。其中read()方法是一次读取一个字节...

lwang_IT
2017/12/24
0
0
socket获取数据 获取流超时

首先请查看一下JavaAPI,可以看到InputStream读取流有三个方法,分别为read(),read(byte[] b),read(byte[] b, int off, int len)。其中read()方法是一次读取一个字节,鬼都知道效率是非常低...

todostyles
2017/11/06
0
0
Android开发 socket

这几天完全被socket 卡住了, 主要原因就是就ip,Socket通信主要有俩种,1,TCP,2,UDP 一,什么时候SOCKET通信: 你经常听到人们谈论着 “socket”,或许你还不知道它的确切含义。现在让我...

DURONG
2012/05/04
0
4
通过JDBC和Hibernate对Clob和Blob的操作

本文主要简介通过JDBC和Hibernate对Clob和Blob的操作,插入和读取. 一,JDBC方式: 1,当lob的内容很小的时候,用sta.setString(2, "clob content"); sta.setBytes(3, "blob".getBytes()); 2,通过...

晨曦之光
2012/04/25
310
0
Android开发入门——Socket编程

1、 Socket通信模型如下: 应用程序通过套接字可以进行通信,可以使用udp协议或者使用tcp协议,当客户端和服务器端的协议时相对应的,客户端使用tcp,那么服务器端使用tcp 2、 UDP协议:把数据...

sflfqx
2013/03/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

分布式缓存架构设计

零、 题记 在高并发场景下,需要通过缓存来减少数据库的压力,使得大量的访问进来能够命中缓存,只有少量的需要到数据库层。由于缓存基于内存,可支持的并发量远远大于基于硬盘的数据库。所以...

Ala6
29分钟前
2
0
简单工厂模式

public abstract class Operation { private double numberA = 0; private double numberB = 0; public double getNumberA() { return numberA; } ......

NinjaFrog
32分钟前
1
0
git(一) 基本操作(branch、tag、冲突)

layout: blog istop: true title: "git基本操作(branch、tag、冲突)" date: 2018-09-11 category: 版本控制 tags: - 版本控制 撤销操作 修改最后一次提交 解释:修改上次提交。可以修改内容...

开心的哈士奇
34分钟前
1
0
Vue中路由管理器Vue Router使用方式(二)-推荐

一、Vue中使用Vue Router简单方式使用 vue add xxx命令添加插件 使用步骤,本人假设已经安装好了Vue CLI工具,了解更多参考:VSCode 搭建Vue开发环境之Vue CLI 1.创建项目 vue create hello...

tianma3798
47分钟前
1
0
设计模式(十六)[结构模式] 装饰模式(Decorator)

1.什么是装饰模式? 装饰模式又名包装模式。装饰模式以对客户端透明的方式扩展对象功能,是继承关系的一个替代方案。 2.模式的类图 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收...

1527
48分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部