根本区别在于字节流以byte为单位处理二进制数据且不涉及编码,字符流以char为单位处理文本并自动进行编码转换;前者适用于图片、音频等非文本文件,后者适用于文本文件如.txt、.json。

Java 中字节流和字符流的根本区别在于它们处理数据的单位、适用对象和编码行为不同。选对流类型,直接影响程序是否能正确读写文件、避免乱码或数据损坏。
数据单位与底层表示不同
字节流以 8 位字节(byte) 为基本单位,直接操作原始二进制数据;字符流以 16 位 Unicode 字符(char) 为单位,面向文本语义。这意味着:
- FileInputStream 读出的是 raw byte 值,比如
0xFF或0x41,不解释含义 - FileReader 读出的是 Java 内部的 char,比如
'中'或'A',已解码完成 - 一个中文字符在 UTF-8 中可能占 3 个字节,但对字符流来说,它就是一个 char
是否自动处理字符编码
字节流 完全不关心编码,它只是忠实地搬运字节;字符流则 内置编码转换逻辑,读写时会按指定编码(如 UTF-8、GBK)完成字节 ↔ 字符的双向转换:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用 FileInputStream 读文本文件,得到的是字节数组,需手动用
new String(bytes, "UTF-8")解码才可能正确 - 用 FileReader(默认使用系统编码)或
InputStreamReader(new FileInputStream(...), "UTF-8"),解码由流自动完成 - 若用字符流去读图片文件,某些字节序列会被误转为非法字符,导致数据失真
类体系与命名规律清晰可辨
Java 的 IO 类设计有明确分层和命名约定:
立即学习“Java免费学习笔记(深入)”;
- 所有字节输入流继承自 InputStream,输出流继承自 OutputStream;典型实现:FileInputStream、BufferedOutputStream、ObjectOutputStream
- 所有字符输入流继承自 Reader,输出流继承自 Writer;典型实现:FileReader、BufferedWriter、PrintWriter
- 类名后缀是重要线索:以 Stream 结尾的是字节流,以 Reader/Writer 结尾的是字符流
实际使用必须匹配数据类型
不是“哪个更好”,而是“哪个合适”:
- 处理图片、音频、ZIP、序列化对象等 —— 必须用 字节流
- 读写 .txt、.csv、.json、.xml 等纯文本 —— 推荐用 字符流,省去编码管理,降低乱码风险
- 需要桥接两者时,用 InputStreamReader / OutputStreamWriter,它们是字节流到字符流的“翻译器”

















