FileInputStream和FileOutputStream是Java基础字节流类,用于读写二进制文件;前者逐字节读取不涉及编码,后者原样写入支持覆盖或追加,均需正确关闭资源并避免用于文本处理。

FileInputStream 和 FileOutputStream 是 Java 中最基础的字节流类,直接操作底层二进制数据,适合读写图片、音频、视频、序列化对象等非文本文件。
FileInputStream:按字节读取二进制文件
它从指定文件中逐字节(或批量)读取原始字节,不涉及字符编码,因此不会因编码问题损坏数据。
- 构造时传入 File 对象或文件路径字符串,文件必须存在且可读,否则抛出 FileNotFoundException
- 常用读取方式:
- read():返回一个 int(0–255),读到末尾返回 -1;每次只读 1 字节,效率低,仅用于简单场景
-
read(byte[] b):将最多
b.length字节读入数组,返回实际读取字节数;推荐用于中等大小文件 -
read(byte[] b, int off, int len):从数组
b的off索引开始,最多写入len字节;适合精细控制缓冲区
- 使用后务必调用 close(),或用 try-with-resources 自动释放资源(强烈推荐)
FileOutputStream:按字节写入二进制文件
它将字节序列原样写入文件,不作任何转换,适用于保存原始二进制内容。
- 构造时传入文件路径,若文件不存在则自动创建;若文件已存在,默认会覆盖原有内容(加
true参数可追加写入) - 常用写入方式:
-
write(int b):写入低 8 位(即
b & 0xFF),适合单字节逻辑 - write(byte[] b):写入整个字节数组
-
write(byte[] b, int off, int len):写入数组中从
off开始的len个字节
-
write(int b):写入低 8 位(即
- 写入完成后建议调用 flush() 确保数据真正落盘(尤其在未 close 前需确保写出),再 close
典型用法:复制一个二进制文件
以下代码演示如何用 FileInputStream + FileOutputStream 完成安全、高效的文件复制:
立即学习“Java免费学习笔记(深入)”;
try (FileInputStream fis = new FileInputStream("source.jpg");
FileOutputStream fos = new FileOutputStream("copy.jpg")) {
byte[] buffer = new byte[8192]; // 8KB 缓冲区,兼顾内存与性能
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
// 自动 flush + close,无需手动调用
} catch (IOException e) {
e.printStackTrace();
}
注意:缓冲区大小不是越大越好,8KB~64KB 是常见合理范围;过小导致系统调用频繁,过大浪费堆内存。
注意事项与常见误区
-
别用它们处理文本文件:如需读写中文文本,请改用
InputStreamReader/OutputStreamWriter包装,指定 UTF-8 等编码 - 不要把 read() 返回值直接当 char 或 String 处理:它只是字节值(0–255),不是 Unicode 字符
-
路径中的反斜杠要转义或用正斜杠:Windows 下写
"C:\data\test.bin"或"C:/data/test.bin" -
权限与路径有效性需提前检查:IO 异常(如
AccessDeniedException、SecurityException)可能在运行时才暴露


















