认识BufferedReader的readLine、ready,以及InputStream的available

最近,同学做实验的时候,在读取服务器端返回的时候,使用了BufferedReader类的readLine,他是这么写的,while(reader.ready()) {//执行读取操作,即readLine

}这个方法很经常被用到, 但是返回的却都是空,这是什么原因呢,查看了一下帮助文档,以及上网查了查,总结如下:

ready是查看流是否已经准备好被读,是一个非阻塞的方法,所以会立刻返回,由于服务器没有准备好被读,所以会立刻返回,所以读取到的都是null,那么我们用while((str = reader.readLine()) != null)进行读取呢,readLine是一个阻塞的方法,只要没有断开连接,就会一直等待,直到有东西返回,那么什么时候返回空呢,只有读到数据流最末尾,才返回null   ,举例如,一般只有在读到文件末尾时才会是空,至于读取服务器端的数据,一般不会是空,那么有时候我们采用特定的字符来代表结束,在网络上,一直等待输入,即使是对方什么也不输入,只是回车,readline也不会返回null,如果I/O中断,会返回I/O异常,还是不会返回null   除非你使用的数据流有固定长度(比如文件数据流,或者ByteArrayInputStream之类),而不是网络数据流(阻塞模式)。   在I/O阻塞模式下,你写的条件循环,是不合理的:   while((line   =   in.readLine())   !=   null)      应该如下:   while(网络状态)//状态可由从客户端读入数据时捕捉I/O异常来获取,所以如果要编写多用户服务程序,最好使用java.nio,他对这方面的处理会比单纯的阻塞IO会更好。

同理,InputStream的available也是非阻塞的,在网络中,很可能流延迟传输(而不是到达不了,服务器端很容易使用这样的代码,而是应用发生错误:

    byte[] bytes = new byte[in.available()];

    in.read(bytes);

结果是错误的,因为available返回的是0

那么解决方法有很多,比如可以一个一个字节的读,或者一个缓存大小字节的读,每次读都是阻塞方式的。所以可以放心

转自:http://blog.csdn.net/neusoftware_20063500/article/details/3723176

原文地址:https://www.cnblogs.com/byron0918/p/4691678.html