Java中读取图片二进制数据必须用FileInputStream等字节流,不可用FileReader等字符流;中小文件可一次性读入byte[],大文件需分块读取并用ByteArrayOutputStream收集。

Java 中用字节流读取图片文件的二进制数据,核心是使用 FileInputStream(输入字节流),因为它能原样读取文件的每一个字节,不作任何编码转换——这正是处理图片、音频、视频等非文本文件所必需的。
用 FileInputStream 一次性读到字节数组
适合中小尺寸图片(如几百 KB 以内)。直接把整个文件内容读入一个 byte[],简单直观:
File file = new File("logo.png");
byte[] data = new byte[(int) file.length()]; // 注意:文件不能太大(如 >2GB 可能出问题)
try (FileInputStream fis = new FileInputStream(file)) {
fis.read(data); // read() 返回实际读取字节数,此处可省略判断(因已预分配足量空间)
} catch (IOException e) {
e.printStackTrace();
}
// 此时 data 就是图片的完整二进制数据
⚠️ 注意:file.length() 返回 long,需强转为 int;若文件超过 Integer.MAX_VALUE(约 2.1GB),会抛异常,此时应改用分块读取。
用 FileInputStream 分块读取(推荐,更健壮)
适用于任意大小图片,内存友好,避免一次性加载大文件导致 OOM:
立即学习“Java免费学习笔记(深入)”;
- 定义固定缓冲区(如 8192 字节),循环调用
read(byte[] b) - 每次返回实际读取字节数(可能小于缓冲区长度,最后一次可能为 -1)
- 用
ByteArrayOutputStream动态收集所有字节
File file = new File("photo.jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[8192];
int len;
while ((len = fis.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
byte[] imageData = baos.toByteArray(); // 最终得到完整二进制数据
读取后怎么验证或使用?
拿到 byte[] imageData 后,常见用途包括:
- 写回文件:
Files.write(Paths.get("copy.png"), imageData) - 转成 Base64 用于前端显示:
Base64.getEncoder().encodeToString(imageData) - 构建 HTTP 响应体(如 Spring Boot 返回图片流)
- 传给图像处理库(如
ImageIO.read(new ByteArrayInputStream(imageData)))
⚠️ 不要用 String 包装二进制数据(比如 new String(imageData)),会因字符编码损坏图片内容。
小提示:别用字符流读图片
FileReader、BufferedReader 等字符流会尝试按指定编码(如 UTF-8)解码字节,而图片数据不是合法文本,会导致乱码、截断甚至抛 MalformedInputException。务必坚持用字节流(InputStream 及其子类)。


















