java io应按数据类型选流:字节流处理二进制,字符流处理文本并显式指定编码(如utf-8);必须用try-with-resources自动关流,禁用filereader/filewriter及默认编码,避免乱码与资源泄漏。

Java 中字节流(InputStream/OutputStream)适合处理二进制数据(如图片、音频、序列化对象),字符流(Reader/Writer)专用于文本,自动处理字符编码。规范编写 IO 代码的核心是:明确数据类型、正确选择流类、用 try-with-resources 自动释放资源、显式指定编码(尤其字符流),避免使用平台默认编码。
字节流:优先用 Buffered + try-with-resources
直接使用 FileInputStream/FileOutputStream 效率低,应包裹缓冲流;必须关闭资源,推荐 try-with-resources 语法,无需手动 close()。
- 读文件(字节):
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg"))) { /* 读取逻辑 */ } - 写文件(字节):
try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.jpg"))) { /* 写入逻辑 */ } - 复制示例:用
byte[] buf = new byte[8192]循环read(buf)和write(buf, 0, len),避免单字节操作
字符流:必须显式指定字符集,禁用平台默认编码
FileReader/FileWriter 不接受编码参数,内部用 Charset.defaultCharset(),极易引发乱码——生产环境严禁使用。应改用 InputStreamReader + FileInputStream 或 OutputStreamWriter + FileOutputStream,并传入标准编码(如 StandardCharsets.UTF_8)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 读文本:
try (InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), StandardCharsets.UTF_8); BufferedReader br = new BufferedReader(isr)) { /* readLine() */ } - 写文本:
try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"), StandardCharsets.UTF_8); BufferedWriter bw = new BufferedWriter(osw)) { /* write() + newLine() */ } - 注意:
BufferedWriter的newLine()是跨平台换行,比硬写"\n"更可靠
网络与内存场景:按需选用对应流类型
Socket 通信、HTTP 响应体等原始数据走字节流;JSON/XML/HTML 等文本内容若需解析,先用字节流接收再转为字符流(或直接用支持编码的工具类如 InputStreamReader);内存中字符串 ↔ 字节数组转换,用 String.getBytes(Charset) 和 new String(bytes, Charset),不依赖默认编码。
- HTTP 响应体读取(已知 UTF-8):
new InputStreamReader(httpConn.getInputStream(), StandardCharsets.UTF_8) - 字符串转字节数组:
"你好".getBytes(StandardCharsets.UTF_8)(不是"你好".getBytes()) - 字节数组转字符串:
new String(bytes, StandardCharsets.UTF_8)
常见反模式与规避方式
以下写法看似简洁,实则隐患明显:
-
错:
new FileReader("a.txt")—— 编码不可控 → 改:用InputStreamReader显式指定 UTF-8 -
错:
fos.write(str.getBytes())—— 用默认编码 → 改:用str.getBytes(StandardCharsets.UTF_8) -
错:手动
finally块关流,未处理close()异常 → 改:统一用 try-with-resources(JDK 7+) -
错:用
DataInputStream.readLine()(已废弃且编码不安全)→ 改:用BufferedReader.readLine()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










