java处理图片须用字节流(fileinputstream/fileoutputstream),禁用字符流;小图可readallbytes到内存,大图宜缓冲复制;写入需用flush确保落盘,注意读写长度一致、路径权限及异常处理。

Java 中用字节流读写图片,核心是使用 FileInputStream 和 FileOutputStream,因为图片是二进制文件,必须用字节流处理,不能用字符流(否则会损坏数据)。
读取图片到内存(字节数组)
适合小图或需要后续处理的场景。注意要完整读取所有字节,避免只读一部分。
- 用
FileInputStream打开图片文件 - 调用
readAllBytes()(JDK 9+)或手动循环读取到字节数组 - 关闭流(推荐 try-with-resources 自动释放)
try (FileInputStream fis = new FileInputStream("input.jpg")) {
byte[] data = fis.readAllBytes(); // 完整读取
// 后续可写入、压缩、加密等
}
直接复制图片文件(不加载内存)
适合大图或单纯拷贝/移动,节省内存。用缓冲区提升效率,避免单字节读写。
- 创建固定大小缓冲区(如 8192 字节)
- 循环
read(byte[])→write(byte[], int, int) - 每次读取返回实际字节数,需用该值控制写入长度
try (FileInputStream fis = new FileInputStream("src.jpg");
FileOutputStream fos = new FileOutputStream("dst.jpg")) {
byte[] buf = new byte[8192];
int len;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len); // 必须用 len,不是 buf.length
}
}
写入图片到磁盘(从字节数组或流)
无论来源是网络响应、数据库 BLOB 还是内存处理结果,最终保存都靠 FileOutputStream。
- 构造时传入目标路径,可加
true参数追加(但图片一般不追加) - 直接调用
write(byte[])写入全部字节 - 务必调用
flush()确保数据落盘(虽然 close 也会 flush,但显式更稳妥)
byte[] imgData = getImageFromNetwork(); // 假设已获取
try (FileOutputStream fos = new FileOutputStream("output.png")) {
fos.write(imgData);
fos.flush();
}
注意事项和常见坑
字节流操作图片看似简单,但几个细节不注意就会导致图片打不开。
- 别用 FileReader / FileWriter:它们是字符流,会按默认编码解析字节,必然损坏图片
-
读写长度必须一致:写入时若用
write(buf)而不是write(buf, 0, len),末尾可能写入旧数据 -
路径和权限检查:确保目标目录存在、有写权限,否则抛
IOException -
异常处理:捕获
IOException,不要忽略;大文件建议加超时或进度提示
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











