核心是字节流不处理编码,字符流必须显式指定编码;乱码本质是字节与字符间“翻译”错配:字节流读写中文需用一致charset转字符串或生成字节,字符流须用inputstreamreader/outputstreamwriter绑定standardcharsets.utf_8,避免依赖默认编码。

核心就一条:字节流不处理编码,字符流必须显式指定编码。乱码不是流本身的问题,而是字节和字符之间“翻译”错了。
字节流读写中文的正确姿势
字节流(InputStream/OutputStream)只管搬运原始字节,不管内容是中文还是图片。所以它本身不会乱码,但你后续怎么解释这些字节,决定了是否乱码。
- 读取后转字符串时,必须用与文件实际编码一致的 Charset:
byte[] bytes = Files.readAllBytes(Paths.get("data.txt"));
String content = new String(bytes, StandardCharsets.UTF_8); // 不能省略编码参数
- 写入前,也要明确字节来源的编码:
String text = "你好";
byte[] utf8Bytes = text.getBytes(StandardCharsets.UTF_8); // 指定UTF-8生成字节
out.write(utf8Bytes);
- 避免使用无参 getBytes() 或 new String(byte[]) —— 它们依赖系统默认编码(Windows 是 GBK),极易出错。
字符流必须绑定编码,不能靠默认
字符流(Reader/Writer)本质是“字节流 + 解码器”,它自动把字节转成 char。但这个解码器用什么规则,必须你来指定。
- 不要这样写(平台相关,高危):
Reader reader = new FileReader("data.txt"); // 默认用 Charset.defaultCharset()
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 要这样写(编码自控):
Reader reader = new InputStreamReader(
new FileInputStream("data.txt"), StandardCharsets.UTF_8);
Writer writer = new OutputStreamWriter(
new FileOutputStream("out.txt"), StandardCharsets.UTF_8);
- BufferedReader/BufferedWriter 同理,包装时就要把编码固定住。
确认并统一编码源头
光代码写对还不够,得知道文件、终端、IDE、甚至编辑器保存时用的是什么编码。
- 查文件真实编码(Linux/macOS):
file -I data.txt
# 或用 Python 工具:chardetect data.txt
- 查 Java 当前默认编码(用于排查):
System.out.println(Charset.defaultCharset());
- IDE(如 IntelliJ)里检查文件编码设置,确保“File Encoding”和“Project Encoding”一致,推荐全项目设为 UTF-8。
- 文本编辑器(如 VS Code、Notepad++)保存文件时,手动选“UTF-8 without BOM”。
网络与控制台输出别漏掉
读写文件只是常见场景,HTTP 响应、Socket 通信、控制台打印同样会乱码。
- Servlet 输出中文时,设响应头:
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
- Socket 通信中,务必用 InputStreamReader/OutputStreamWriter 包装,并传入 StandardCharsets.UTF_8。
- 控制台输出乱码?多数是终端不支持 UTF-8 或 JVM 启动参数未指定,可加:-Dfile.encoding=UTF-8。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










