转载于:http://yyzjava.iteye.com/blog/1178525

要搞清楚read(byte[] b)和readFully(byte[] b)的区别,可以从以下方面着手分析:

1.代码的具体实现

2.方法何时返回

3.字节是以什么方式在网络上传输的

1.read(byte[] b)调用read(byte[] b,0,b.length),其中的部分关键代码如下

int c = read();//读取字节流中的下一个字节
if (c == -1) {
return -1;
}
b[off] = (byte)c; int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) { }
return i;

readFully(byte[] b)调用readFully(byte[] b,0,b.length),其中的部分关键代码如下

int n = 0;
while (n < len) {//该方法一直阻塞,直到读取到字节数据缓冲区装满
int count = in.read(b, off + n, len - n);
if (count < 0)
throw new EOFException();
n += count;
} //read(bytes[] b,int off,int len)中的关键代码
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c; int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) { }
return i;

2.从以上代码,我们可以看到,read(byte[] b)一直阻塞等待读取字节,直到字节流中的数据已经全部读完。而readFully(byte[] b)是当数据缓冲区的空间还有剩余时会阻塞等待读取,直到装满。

3.下图反映了字节流数据是如何通过网络的

应用程序用输出流将数据输入TCP的发送缓存中,这些数据被分割成TCP认为最适合发送的数据块(报文段或段)。报文段通过网络的传输到达指定地址(URL)的TCP接收缓存中,接收到的报文段很有可能不是顺序到达的,但TCP可以根据报文段的序号进行排序并存储在TCP接收缓存中。应用程序如果需要获得这些数据,需要通过输入流读取并解析这些报文段。

通过分析以上三个问题,我们可以解释以下代码存在的问题:

//发送端:
OutputStream out = ......;//通过TCP连接得到输出流对象
String content = "...";
byte[] data = content.getBytes();
output.write(data);
int len = data.length;
while (len++ < 30) {
output.writeByte('\0');//补够30个字节
}
//接收端:
InputStream in = ......;//通过TCP连接得到输入流对象
byte[] bytes = new byte[30];
in.read(bytes);

由于字节数据是在网络中通过TCP连接进行传输,这些数据刚刚到达接收端(存储在TCP接收缓冲区)的可能只是其中的一部分数据,其他的数据可能还在传输中甚至在发送端的TCP缓存中。在调用read(byte[] b)读取数据时,b中得到的就是发出的30个字节的一部分。

要想完全获得这30个字节数据,合理的方法是用readFully(byte[] b)读取,因为该方法会一直阻塞等待,直到30个数据全部到达(数据缓冲区装满)

最新文章

  1. Prototype之个人见解
  2. 在eclipse中安装上genymotion插件
  3. leetcode52. N-Queens II
  4. Google -We’re Sorry....
  5. c++ 继承多个类 及虚函数
  6. POJ 1459 Power Network(网络最大流,dinic算法模板题)
  7. Linq-表达式常用写法
  8. ThinkPHP - 自定义标签库 - 标签驱动
  9. 5 MySQL索引
  10. 每天一个Linux命令(08)--cp命令
  11. 记一次sql server 性能调优,查询从20秒至2秒
  12. CSV导出大量数据
  13. 使用Jenkins部署asp.net core
  14. HDU - 1698 Just a Hook (线段树区间修改)
  15. python3+selenium框架设计05-配置文件和浏览器引擎类
  16. python中的递归小实例
  17. python 基础总结1
  18. 在WinForm应用程序中嵌入WPF控件
  19. asp.net cors solution
  20. (转)python+opencv实现动态物体追踪

热门文章

  1. Windows7(x86) xampp php5.5 imagick install
  2. servlet forword服务器端跳转
  3. HDU 3709 Balanced Number (数位DP)
  4. TDB文件介绍
  5. java abstraction and encapsulation
  6. python之函数的初识
  7. Bootstrap历练实例:默认的进度条
  8. ios 设计模式总结
  9. 无法重启ssh
  10. 安装ElasticSearch 6.1.1 head插件