转载于: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个数据全部到达(数据缓冲区装满)

read(byte[] b)与readFully(byte[] b)的更多相关文章

  1. java int转byte和long转byte

    在网络编程中,出于节约带宽或者编码的需要,通常需要以原生方式处理long和int,而不是转换为string. public class ByteOrderUtils { public static b ...

  2. 【转】java中byte, int的转换, byte String转换

    原文网址:http://freewind886.blog.163.com/blog/static/661924642011810236100/ 最近在做些与编解码相关的事情,又遇到了byte和int的 ...

  3. java中write(byte[] b)与write(byte[] b,int off,int len)区别

    public static void copyInputStreamT0OutputStream(InputStream in, OutputStream out) { byte[] buffer = ...

  4. 从一个URL下载原始数据,基于byte字节,得到byte数组

    public static byte[] loadRawDataFromURL(String u) throws Exception { URL url = new URL(u); HttpURLCo ...

  5. 获取文件数据流+叠加byte数组(给byte数组加包头包尾)

    OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "(*.mp4)|*.mp4|(*.*)|*.*"; ofd.Res ...

  6. c# 字符串转Byte[],如何将Byte[]插入到Oracle Blob

    byte[] xx=Encoding.Default.GetBytes("12121232"); 插入数据库 string sqlStr = "update sys_ta ...

  7. 输入流当中的read方法和readfully方法的区别与原理

    原文链接:https://blog.csdn.net/yangjingyuan/article/details/6151234?locationNum=3 DataInputStream类中的read ...

  8. Java知IO

    ---恢复内容开始--- Java将IO(文件.网络.终端)封装成非常多的类,看似繁杂,其实每个类的具有独特的功能. 按照存取的对象是二进制还是文本,java使用字节流和字符流实现IO. 流是java ...

  9. Java-IO之对象输入流输出流(ObjectInputStream和ObjectOutputStream)

    ObjectInputStream和ObjectOutputStream的作用是对基本数据和对象进行序列化操作支持.创建文件输出流对应的ObjectOutputStream对象,该ObjectOutp ...

随机推荐

  1. 弄了一个星期的wp 8.1,吐血的感觉

    看到8.1出来这么久了,心痒难耐,忍不住想重新把应用写一遍,于是上个星期开始动手,用的mvvm模式,结果一路下来,sqlce不能用了,那好吧,我用sqlite,webrequest变成httpclie ...

  2. ArcGis server发布地图服务

    ArcGIS server发布服务: 首先修改地图文档属性中的关联默认数据库 最后使用分享将地图服务发布到server上,是地图服务可以使用: 注意一定要勾选 Feature Access选项 fea ...

  3. fork新建进程

    #include <sys/types.h>#include<sys/wait.h>#include<unistd.h>#include<stdio.h> ...

  4. E - Polycarp and Snakes

    E - Polycarp and Snakes 题意:在一个全是点的图上开始画线,每次将一行或一列任意长度染成字母,一笔染一种字母,字母必须从a开始连续到后面某个字母可以覆盖. 问所给图案是否满足 , ...

  5. iframe的document操作

    导语: 在我写网页代填插件的时候,有遇到拿不到input元素的时候,这时候我去看元素布局,发现有些网站登录那一块是用iframe标签写的,这时候我需要取到的那就是iframe标签下input元素 1. ...

  6. js函数式编程(一)-纯函数

    我将写的第一个主题是js的函数式编程,这一系列都是mostly adequate guide这本书的读书总结.原书在gitbook上,有中文版.由于原作者性格活泼,书中夹杂很多俚语,并且行文洒脱.中文 ...

  7. 【数论分块】bzoj2956: 模积和

    数论分块并不精通……第一次调了一个多小时才搞到60pts:因为不会处理i==j的情况,只能枚举了…… Description $\sum_{i=1}^{n}\sum_{j=1 \land i \not ...

  8. python爬虫: 豆瓣电影top250数据分析

    转载博客 https://segmentfault.com/a/1190000005920679 根据自己的环境修改并配置mysql数据库 系统:Mac OS X 10.11 python 2.7 m ...

  9. linux SVN安装及配置教程

    1.环境centos6.4 2.安装svnyum -y install subversion 3.配置 建立版本库目录mkdir /www/svndata svnserve -d -r /www/sv ...

  10. day24 02 单继承(派生)

    day24 02 单继承(派生) 1.首先来看一个简单的例子 比如: 狗类的属性有:吃,喝,看门 鸟类的属性有:吃,喝,下蛋 看门和下蛋就是这两种动物不同的属性,而吃喝是两个共同的属性 以下代码实现了 ...