关于字节流读取,int和byte的区别

bilifo 2016-01-25 11:25:11
大体是读传来的字节数据。但发现用int接收和byte接收有一点区别
问题源码如下:
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
mFileInputStream = (FileInputStream)getInputStream();
byte[] temp = null;
while (!isInterrupted()) {
temp = null;
if (mFileInputStream != null) {
try {
int i = 0;
int bb;
temp = new byte[1024];
do {// 一个字节一个字节的读
bb = mFileInputStream.read();//当读到最后个字节时,也就是-1,程序就在这里停下了了,没有去执行后面的list.add(),导致list.size为0
temp[i] = (byte)bb;
i++;
} while (bb!=-1); // 保证结束符为-1

if(flag==true){//清空ArrayList集合,释放资源
list.clear();
}//用ArrayList<byte[]>来存放byte数组,这样能缓存接收的数据
list.add(Arrays.copyOf(temp, i));//用Arrays.copyOf()来传递,可以确定这个数组的具体长度
flag=false;//把标志位改回不清空状态
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

而用byte的可行源码如下:
/**
* 接收,当收到“0xf5”时,就会结束。单开一个线程来进行接收才有效果。
*/
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
mFileInputStream = (FileInputStream)getInputStream();
byte[] temp = null;
while (!isInterrupted()) {
temp = null;
if (mFileInputStream != null) {
try {
int i = 0;
byte bb;
temp = new byte[1024];
do {// 一个字节一个字节的读
bb = (byte)mFileInputStream.read();
temp[i] = bb;
i++;
} while (bb!=(byte)0xf5); // 保证结束符为-1

if(flag==true){//清空ArrayList集合,释放资源
list.clear();
}//用ArrayList<byte[]>来存放byte数组,这样能缓存接收的数据
list.add(Arrays.copyOf(temp, i));//用Arrays.copyOf()来传递,可以确定这个数组的具体长度
flag=false;//把标志位改回不清空状态
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
由于read()方法的返回值为int型的-1时,表示后面没数据了,前一个有问题片段中“bb = mFileInputStream.read()”,用int型的bb来接收read(),当它得到返回是-1,它似乎立即停掉了当前线程,导致后面的list.add()方法没有实行,最后的list.size为0.而后有一个片段,用byte型的bb来接收read(),判断结束位“f5”,可以正常执行到list.add()。那么,就有问题了,read()的源码里是如何去判断结束符的?为什么read()到结束符后,它会停掉当前线程或者说是跳出了当前程序(反正没有执行到后面的list.add()方法)?
...全文
384 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
daker_129 2016-01-27
  • 打赏
  • 举报
回复
什么情况?解决没有?怎么解决的?代码贴出来看看
bilifo 2016-01-25
  • 打赏
  • 举报
回复
引用 1 楼 oh_Maxy 的回复:
你的循环是不是应该这样: while((bb = mFileInputStream.read()) != -1){ ... }
改成这样,read()也会阻塞
oh_Maxy 2016-01-25
  • 打赏
  • 举报
回复
你的循环是不是应该这样: while((bb = mFileInputStream.read()) != -1){ ... }
shixitong 2016-01-25
  • 打赏
  • 举报
回复
阻塞其实就是必须先做完某件事,才能有后续事项,阻塞是没有时间的(不可控),但是你可以设置超时,比如规定你读2s,超过2s就挂掉,但是就算设置超时时间,也不是很好,比如我还没读完呢,就超时了,那就歇菜了 我所说的固定长度不是byte[1024]这个,比如有服务器和客户端,这个时候双方约定,比如前32(按int 算)个字节,我们存要传的内容的字节长度,后面就放具体的内容,传输的内容就为:[(内容字节的长度)的字节]+[内容字节],加号前面这部分是固定的长度,这个时候到读的时候,先in.read(readbyte,0,32);下,这个时候readbyte里存放就是传输内容的长度的bit值,然后把bit值转为int,这个时候得到的就是要传输内容的字节长度,然后再读取n长度的字节就ok了
bilifo 2016-01-25
  • 打赏
  • 举报
回复
引用 5 楼 shixitong 的回复:
read() 方法是阻塞的,你第一个ReadThread 代码段里的getInputStream()是一个网络流吧?如果是网络流应该是流的那一头还在传输数据或者传输完了,但是没有关闭流,这个时候会一直阻塞,第二个就很好理解了,读到某个字符就结束读取,一般我们传数据会采用这种方法,还可以在流的开头固定长度写入要传输内容的长度,这样读取的时候就不需要判断字符了,只需要读取要传输内容的长度,然后读取对应的长度就可以了
其实是串口通信,不过也可以看成网络通信。由于返回的数据长度不一定,有长有短,如果都按照byte[1024]来接收传来的数据,感觉有点浪费,而且效率也不高,所以就没按照固定长度的方式来做。虽然可以自己约定“结束符”但感觉不太通用,给别人也不方便。就想着直接读到结尾,没有数据了,就把信息给出了。不知道阻塞的原理是怎样的,有没有办法设置它的阻塞时间
shixitong 2016-01-25
  • 打赏
  • 举报
回复
read() 方法是阻塞的,你第一个ReadThread 代码段里的getInputStream()是一个网络流吧?如果是网络流应该是流的那一头还在传输数据或者传输完了,但是没有关闭流,这个时候会一直阻塞,第二个就很好理解了,读到某个字符就结束读取,一般我们传数据会采用这种方法,还可以在流的开头固定长度写入要传输内容的长度,这样读取的时候就不需要判断字符了,只需要读取要传输内容的长度,然后读取对应的长度就可以了
bilifo 2016-01-25
  • 打赏
  • 举报
回复
不知道有没有方法可以使阻塞的read继续向下执行
bilifo 2016-01-25
  • 打赏
  • 举报
回复
其实并不是int型接收和byte型接收的区别,而是read()方法的阻塞作用,只不过第2段代码通过判断结束符的方式,避开了返回结果为-1的情况,使程序没有进入阻塞就结束了

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧