【Java】BIO流
·
在Java中,BIO(Blocking I/O)是一种传统的、同步的输入输出(I/O)模型。它意味着每次进行I/O操作时,线程会被阻塞,直到数据完全读取或写入完毕。BIO通常是阻塞式的,当程序发出读取或写入请求时,它会等待I/O操作完成才会继续执行后续代码。
BIO的特点:
- 同步阻塞:每次 I/O 操作都会阻塞当前线程,直到操作完成。
- 简单:BIO 是 Java 中最简单的一种 I/O 方式,易于理解和使用。
- 效率较低:由于阻塞模式,BIO 适用于并发量较低的场景,但当需要处理大量并发连接时效率较差。
常见的 BIO 操作:
- 文件 I/O(FileInputStream , FileOutputStream , FileReader , FileWriter)
- 网络 I/O(Socket , ServerSocket)
BIO 在网络编程中的应用
BIO 模式通常用于经典的 Socket 和 ServerSocket,当进行网络通信时,客户端和服务器的每次 I/O 操作都会阻塞,直到读取或写入完成。
BIO 网络示例:
import java.io.*;
import java.net.*;
public class BioServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(12345)) {
System.out.println("Server is waiting for client connection...");
try (Socket socket = serverSocket.accept()) {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
String message;
while ((message = reader.readLine()) != null) {
System.out.println("Received from client: " + message);
writer.println("Server response: " + message);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:
import java.io.*;
import java.net.*;
public class BioClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 12345)) {
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer.println("Hello Server!");
String response = reader.readLine();
System.out.println("Server says: " + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
BufferedWriter 和 PrintWriter 的主要区别
| 特性 | BufferedWriter | PrintWriter |
|---|---|---|
| 写入方法 | 只有 write(),只能写字符或字符数组,需要手动处理换行 | 提供 print() / println() / printf() 方法,可以直接写字符串并自动处理换行 |
| 自动刷新 | 不会自动刷新缓冲区,需要手动调用 flush() | 可以在构造函数里设置 autoFlush = true,在调用 println() 时自动刷新 |
| 方便性 | 适合写大块文本、性能优化(减少系统调用次数) | 适合交互式通信,写一行就立即发给客户端,非常方便 |
| 用途 | 文件写入、日志写入 | 网络通信、控制台输出 |
为什么这个例子用PrintWriter
在我的 BIO 服务器中:
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
- 自动刷新:第二个参数 true 表示每次调用 println() 时都会自动刷新缓冲区,把消息立即发给客户端。
- 方便写行:我们想“一行一行地回传客户端消息”,println() 就可以直接实现。
- 无需手动flush():如果用 BufferedWriter,必须每次写完后调用 flush() 才能让客户端收到数据,否则客户端可能一直阻塞等不到消息。
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("Server response: " + message + "\n");
writer.flush(); // 必须手动刷新,否则客户端收不到
可以工作,但麻烦了一点,而且 PrintWriter 已经封装好了“写一行就发”的功能,非常适合网络通信场景。
总结:
- BIO 是 Java 中最基础的 I/O 操作方式,适用于简单的文件和网络 I/O 操作。
- 在高并发场景下,BIO 的效率较低,因为每个连接都会占用一个线程,容易导致资源浪费和性能瓶颈。
- 如果需要处理大量并发连接,可以考虑 NIO(New I/O)或 AIO(Asynchronous I/O)作为替代方案。
更多推荐


所有评论(0)