虽然写IO方面的程序不多,但BufferedReader/BufferedInputStream倒是用过好几次的,原因是:
- 它有一个很特别的方法:readLine(),使用起来特别方便,每次读回来的都是一行,省了很多手动拼接buffer的琐碎;
- 它比较高效,相对于一个字符/字节地读取、转换、返回来说,它有一个缓冲区,读满缓冲区才返回;一般情况下,都建议使用它们把其它Reader/InputStream包起来,使得读取数据更高效。
- 对于文件来说,经常遇到一行一行的,特别相符情景。
这次是在蓝牙开发时,使用两个蓝牙互相传数据(即一个发一个收),bluecove这个开源组件已经把数据读取都封装成InputStream了,也就相当于平时的IO读取了,很自然就使用起readLine()来了。
发数据:
- BufferedWriter output = new BufferedWriter(new OutputStreamWriter(conn.openOutputStream()));
- int i = 1;
- String message = "message " + i;
- while(isRunning) {
- output.write(message+"/n");
- i++;
- }
读数据:
- BufferedReader input = new BufferedReader(new InputStreamReader(m_conn.openInputStream()));
- String message = "";
- String line = null;
- while((line = m_input.readLine()) != null) {
- message += line;
- }
- System.out.println(message);
上面是代码的节选,使用这段代码会发现写数据时每次都成功,而读数据侧却一直没有数据输出(除非把流关掉)。经过折腾,原来这里面有几个大问题需要理解:
- 误以为readLine()是读取到没有数据时就返回null(因为其它read方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;因为readLine()阻塞后,System.out.println(message)这句根本就不会执行到,所以在接收端就不会有东西输出。要想执行到System.out.println(message),一个办法是发送完数据后就关掉流,这样readLine()结束阻塞状态,而能够得到正确的结果,但显然不能传一行就关一次数据流;另外一个办法是把System.out.println(message)放到while循环体内就可以。
- readLine()只有在数据流发生异常或者另一端被close()掉时,才会返回null值。
- 如果不指定buffer大小,则readLine()使用的buffer有8192个字符。在达到buffer大小之前,只有遇到"/r"、"/n"、"/r/n"才会返回。
readLine()的实质(下面是从JDK源码摘出来的):
- String readLine(boolean ignoreLF) throws IOException {
- StringBuffer s = null;
- int startChar;
- synchronized (lock) {
- ensureOpen();
- boolean omitLF = ignoreLF || skipLF;
- bufferLoop:
- for (;;) {
- if (nextChar >= nChars)
- fill(); //在此读数据
- if (nextChar >= nChars) { /* EOF */
- if (s != null && s.length() > 0)
- return s.toString();
- else
- return null;
- }
- ......//其它
- }
- private void fill() throws IOException {
- ..../其它
- int n;
- do {
- n = in.read(cb, dst, cb.length - dst); //实质
- } while (n == 0);
- if (n > 0) {
- nChars = dst + n;
- nextChar = dst;
- }
- }
从上面看出,readLine()是调用了read(char[] cbuf, int off, int len) 来读取数据,后面再根据"/r"或"/n"来进行数据处理。
在Java I/O书上也说了:
public String readLine() throws IOException
This method returns a string that contains a line of text from a text file. /r, /n, and /r/n are assumed to be line breaks and are not included in the returned string. This method is often used when reading user input from System.in, since most platforms only send the user's input to the running program after the user has typed a full line (that is, hit the Return key).
readLine() has the same problem with line ends that DataInputStream's readLine() method has; that is, the potential to hang on a lone carriage return that ends the stream . This problem is especially acute on networked connections, where readLine() should never be used.
小结,使用readLine()一定要注意:
- 读入的数据要注意有/r或/n或/r/n
- 没有数据时会阻塞,在数据流异常或断开时才会返回null
- 使用socket之类的数据流时,要避免使用readLine(),以免为了等待一个换行/回车符而一直阻塞
相关推荐
好东西大家分享 ,简单程序初学者适用.老师课堂示范用例,经典。
客户端和服务器端通过io流进行通讯。服务器端将用户的信息进行处理之后返回给客户端。
Angular-ngx-socket-io.zip,角6NGX插槽IO的socket.io模块,Angularjs于2016年发布,是Angularjs的重写版。它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发人员的web应用程序工作流...
Socket.IO 的流模块 这个库是对节点模块的更新。 没有进行代码更改,但已更新debug模块以避免现有项目中的安全漏洞。 要求 node.js 4.x 或更高版本 下载安装 npm install @sap_oss/node-socketio-stream 已知的问题...
这是一个java Socket Thread Io 大文件下载上传的整合
Socket.io-文件客户端Socket.io-file-client是用于通过Socket.io上传文件的模块。从1.x到2.x的主要更改Socket.io-file 1.x使用二进制字符串发送文件。 Binary String比直接Binary写慢一点,服务器也使用fs.write,而...
用于做在线聊天室,后台基于node,前台需要引入的js文件
用C#编写的socket.io客户端 用于socket.io的高性能C#客户端。 通过和可选配置实现灵活性。 建立在.NET Standard 2.1之上。 安装 PM> Install-Package Socket.Io.Client.Core 特征 完全异步且无阻塞的灵活API 发出...
mqtt-realtime-chart-server是一个Express.js-MQTT-Socket.io应用程序,可与结合使用。 产品特点 服务器 发布并订阅MQTT主题(例如,电压) 使用websockets将收到的消息转发给客户端 客户 多系列折线图实时数据...
在Merlin之前,编写Socket程序是比较繁琐的工作.因为输入输出都必须同步.这样,对于多客户端客户/服务器模式,不得不使用多线程.即为每个连接的客户都分配一个线程来处理输入输出.由此而带来的问题是可想而知的.程序员...
const io = require ( 'socket.io' ) ; const app = express ( ) ; const server = http . createServer ( app ) ; const socket = io . listen ( server ) ; server . listen ( port , ip ) ; socketFile ( socket ...
前端项目-socket.io-stream,socket.io流
功能简介: 星际争霸游戏项目,该项目实现了单人模式和多人合作模式,可记录游戏进度,新建游戏,载入历史记录等功能,多人模式下可以创建一个区,然后邀请玩家加入一起玩
Angular-ng-socket-io.zip,角度插槽IO的socket.io模块,Angularjs于2016年发布,是Angularjs的重写版。它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发人员的web应用程序工作流。
基于 Java socket + 基础 io 流 + swing 窗口的聊天程序,供学习参考
node.js实现使用socket.io实现通信,后台连接socket获取数据
系统功能包括: 创建用户、恢复用户、用户登录、系统各项...Java swing、Spring、Hibernate、MySql5、Socket、多线程、IO流、JDBC 开发工具:NetBeans7+JDK1.6 服务器地址和端口由config.properties配置,可任意移植
socket.io-live-stream 基于画布的基于socket.io的实时流实验项目
直截了当的编解码器DSL,用于将socket.io回调消息转换为高级流消息类型。文献资料请参阅和文档。示例应用示例应用程序可以在找到。许可和支持该软件的版权为2017 Lightbend,并获得。 Lightbend订阅不包括对此软件...
JAVA+Socket实现文件传输(论文+源代码) JAVA+Socket实现文件传输(论文+源代码) JAVA+Socket实现文件传输(论文+源代码) JAVA+Socket实现文件传输(论文+源代码) JAVA+Socket实现文件传输(论文+源代码) JAVA+Socket实现...