字符流不能读写图片,因为其本质是字节流加编码转换层,会将图片的非法字节序列强制解码为char(如替换成或截断),再编码回字节,导致原始二进制数据失真、文件头损坏、无法打开。

图片等二进制文件必须用字节流处理,不能用字符流。因为字符流会尝试按指定编码(如 UTF-8)解码字节,而图片数据不是合法文本,解码过程会破坏原始字节,导致文件损坏或无法打开。
为什么字符流不能读写图片
字符流(如 FileReader / FileWriter、InputStreamReader / OutputStreamWriter)本质是字节流 + 编码转换层。它会把读入的字节按编码规则转成 char,再拼成字符串;写入时又把 char 按编码转回字节。但图片文件里大量字节组合在 UTF-8 或 GBK 下根本不是有效字符,强行转换会:
- 跳过、替换或截断非法字节序列(如替换成 )
- 改变原始字节数量和顺序
- 导致图片头信息错乱、尺寸异常、打不开或显示为乱码
该用哪些字节流类
处理图片推荐使用以下标准字节流,它们直接操作原始字节,不涉及编码:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- FileInputStream / FileOutputStream:最常用,适合小到中等图片(如几百 KB)
- BufferedInputStream / BufferedOutputStream:套在 FileInputStream/OutputStream 外提升读写效率,尤其适合大图
- Files.copy()(Java 7+):一行代码完成复制,底层自动用字节流,简洁安全
正确示例:复制一张 PNG 图片
✅ 正确做法(字节流):
try (FileInputStream fis = new FileInputStream("input.png");
FileOutputStream fos = new FileOutputStream("output.png")) {
byte[] buffer = new byte[8192];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
✅ 更简洁写法(推荐):
Files.copy(Paths.get("input.png"), Paths.get("output.png"),
StandardCopyOption.REPLACE_EXISTING);
❌ 错误写法(字符流,会导致图片损坏):
// 千万不要这么干!
try (FileReader fr = new FileReader("input.png"); // 解码失败,抛异常或乱码
FileWriter fw = new FileWriter("output.png")) {
// ... 后续逻辑必然出错
}
额外注意点
- 不要用 Scanner 或 PrintWriter 处理图片——它们是面向文本的工具
- 如果需从网络或数据库读取图片,仍要用 InputStream / OutputStream 及其子类
- Base64 编码后的图片字符串是文本,此时可用字符流处理,但那是另一层转换,原始图片本身仍是字节
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










