java中io流封装socket流的核心是将原始字节流逐层包装为字符流和缓冲流,以支持按行读写、utf-8编码、自动刷新等功能,避免乱码、低效和无法readline()等问题。

Java 中 IO 流对 Socket 输入输出流的封装,核心是把原始字节流(InputStream/OutputStream)逐层包装成更易用、功能更强的字符流或缓冲流,从而支持按行读写、自动换行、编码处理等常见操作。
为什么要封装?
Socket 的 getInputStream() 和 getOutputStream() 返回的是裸字节流,不能直接读取字符串,也不带缓冲和编码转换能力。直接使用容易出错,比如:
- 读取中文时乱码(未指定字符集)
- 逐字节读效率低(无缓冲)
- 无法按行读取(
readLine()不可用) - 写入字符串需手动转字节数组并处理换行
标准封装链路(服务端/客户端通用)
典型封装路径遵循“底层字节流 → 编码转换流 → 缓冲流 → 功能增强流”逻辑:
-
输入流封装:
socket.getInputStream()→new InputStreamReader(..., "UTF-8")(指定编码防乱码) →new BufferedReader(...)(支持readLine()、缓冲提升性能) -
输出流封装:
socket.getOutputStream()→new OutputStreamWriter(..., "UTF-8")→new BufferedWriter(...)或直接new PrintWriter(..., true)(true表示自动 flush)
实际代码中怎么写?
以客户端为例,连接后立即封装:
Socket socket = new Socket("localhost", 8080);
// 封装输入流:可按行读,UTF-8 解码
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "UTF-8")
);
// 封装输出流:自动 flush,支持 println
PrintWriter out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream(), "UTF-8"),
true
);
out.println("Hello Server");
String response = in.readLine(); // 阻塞直到收到一行
服务端同理,用 clientSocket.getInputStream() 和 clientSocket.getOutputStream() 做相同封装。
封装时要注意的关键点
-
显式指定字符集:避免依赖平台默认编码(如 Windows 的 GBK),统一用
"UTF-8" -
PrintWriter 的 auto-flush:构造时传
true,否则需手动调flush() -
关闭顺序:先关
PrintWriter/BufferedReader,再关Socket;流关闭会触发底层 socket 关闭(但显式关 socket 更稳妥) -
不要混用流与 socket 关闭:若已用 try-with-resources 管理流,
socket.close()可省略,但建议仍显式调用确保资源释放
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











