虽然写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(),以免为了等待一个换行/回车符而一直阻塞
相关推荐
在这个示例中,我们将深入探讨如何利用Java IO流与Socket实现简单的文本传输。对于初学者来说,理解这两个概念及其交互是非常关键的。 首先,让我们来了解Java IO流。IO流在Java中用于读取和写入数据,它可以是文件...
"weapp.socket.io"是一个专为微信小程序(WeChat Mini Program)定制的Socket.IO实现,它使得在微信环境中可以利用WebSocket进行实时通信。Socket.IO是一个流行的JavaScript库,它提供了跨平台、跨浏览器的实时应用...
客户端和服务器端通过io流进行通讯。服务器端将用户的信息进行处理之后返回给客户端。
首先,`io.socket.client.jar` 是 `socket.io-client` 的核心库,它提供了与服务器端 `socket.io` 服务进行交互的接口。这个库使得Android应用能够创建连接,发送和接收消息,以及处理各种事件,如连接状态变化、...
SocketInputStream和SocketOutputStream分别用于客户端的输入和输出,而ServerSocket可以监听客户端的连接请求,并通过Socket与之建立连接。 在文件操作方面,File类提供了一系列方法来创建、删除、重命名文件和...
三、Socket与ServerSocket 1. ServerSocket:在服务器端,通过创建ServerSocket对象并指定端口号,服务器可以监听特定的TCP端口,等待客户端的连接。一旦有客户端连接,ServerSocket的accept()方法会返回一个新的...
Java中的IO流是Java语言处理输入输出操作的重要组成部分,它为数据传输提供了强大的支持。本文将深入探讨Java的IO流实例应用,旨在帮助开发者更好地理解和掌握这一关键概念。 IO流在Java中分为两大类:字符流...
1. **java-socket.io-client**:这是一个流行的Java实现,提供了与Node.js Socket.IO服务器交互的能力。为了使用这个库,你需要将对应的jar包添加到你的项目类路径中。在压缩包中,你可能会找到类似`socket.io-...
Socket.IO 是一个非常流行的JavaScript库,它能够实现浏览器与服务器之间的实时双向通信。它不仅支持WebSocket协议,还能够通过其他方式(如轮询)作为回退方案,确保在各种环境中都能提供稳定的服务。 #### 二、...
5. **IO流**:Socket通信基于IO流。在Java中,`InputStream`和`OutputStream`分别用于读取和写入数据。在Socket中,我们可以使用`Socket.getInputStream()`和`Socket.getOutputStream()`获取对应的输入流和输出流。 ...
然而,微信小程序并不直接支持原生的Socket.IO库,因为它的运行环境与常规的Web环境有所不同。因此,我们需要找到一种方法将Socket.IO的功能适配到微信小程序中。 "weapp.socket.io.js.zip" 文件正是为了解决这个...
1. **引入socket.io-client库**:由于微信小程序不支持直接引入npm包,你需要先将socket.io-client库转换为小程序可用的格式,这通常通过Babel或者其他构建工具完成。然后将转换后的文件上传至微信开发者工具的项目...
Socket.IO是一个广泛使用的JavaScript库,专门用于开发实时Web应用程序。它允许开发者在客户端(浏览器)与服务器端之间建立实时双向通信,对于即时通讯、推送通知、协作应用程序、在线游戏等多种应用场景尤其有用。...
Java IO流是Java平台中用于处理输入/输出操作的核心组件,它允许程序与各种数据源(如文件、网络连接、内存缓冲区等)进行交互。Java IO流的精讲涵盖了许多概念和技术,包括流的分类、流的方向、缓冲区的使用、字符...
Java IO流是Java平台核心特性之一,它负责在程序与外部资源之间传输数据。这个概念在Java编程中至关重要,因为它提供了处理输入(读取)和输出(写入)的机制,无论是从键盘、文件、网络还是其他数据源。在本文中,...
在Java编程中,IO流(Input/Output Stream)是用来处理数据输入和输出的重要工具。它允许程序与外部设备,如硬盘、网络、内存等进行数据交互。IO流分为两大类:字节流(处理字节数据)和字符流(处理字符数据)。...
这个源码包是 C++ 实现的 Socket.IO 客户端库,名为 "socket.io-clientpp",位于 "socket.io-clientpp-master" 压缩包中。下面将深入探讨相关知识点。 1. **Socket 基础** - **Socket**:Socket 是操作系统提供的...
《Java IO流详解与commons-io-1.4.jar库的应用》 在Java编程语言中,IO(Input/Output)流是一组用于数据传输的类,它们允许程序读取和写入数据,无论是从磁盘、网络还是其他输入输出设备。Java的IO流系统是一个...
Java中的IO流是Java平台提供的一种处理输入输出数据的核心机制,广泛应用于文件读写、网络通信、数据转换等场景。IO流分为字节流(Byte Stream)和字符流(Character Stream),它们构成了Java IO系统的基础。 1. *...
3. **创建客户端**:在客户端(通常是一个HTML页面),你需要引入Socket.IO的客户端库,并建立与服务器的连接。一旦连接建立,你可以监听`connect`事件,然后发送和接收消息。 ```html <script src="/socket.io/...