单纯用 fileinputstream 与 fileoutputstream 无法实现“极速”拷贝,因其无缓冲、单字节读写触发频繁系统调用;提速需批量读写(如8kb字节数组)或nio的transferto。

单纯用 FileInputStream 与 FileOutputStream 无法实现“极速”拷贝——它们是字节流基础类,本身不带缓冲,单字节读写效率极低。真正提速的关键是搭配缓冲(BufferedInputStream / BufferedOutputStream)或使用 NIO 的 transferTo/transferFrom,而不是裸用这两个流。
为什么裸用 FileInputStream + FileOutputStream 很慢?
默认情况下,每次 read() 或 write(int b) 都触发一次系统调用,拷贝 1MB 文件可能产生上百万次调用,开销巨大。
正确做法是:
- 用
read(byte[] b)批量读取(推荐 8KB~64KB 缓冲区) - 避免单字节循环
- 显式关闭流(或用 try-with-resources)
高效拷贝的推荐写法(传统 IO)
使用固定大小字节数组批量传输,不依赖额外包装类,简洁可控:
public static void fastCopy(File src, File dst) throws IOException {
try (FileInputStream fis = new FileInputStream(src);
FileOutputStream fos = new FileOutputStream(dst)) {
byte[] buf = new byte[8192]; // 8KB 缓冲区,兼顾内存与性能
int len;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
}
}
✅ 比单字节快 10 倍以上
✅ 无额外对象创建开销
✅ 兼容所有 JDK 版本
更快的选择:NIO transferTo(Linux/Unix 下接近零拷贝)
如果源和目标都是文件且位于同一文件系统(尤其 Linux),用 FileChannel.transferTo() 可绕过 JVM 堆内存,由内核直接搬运:
public static void ultraFastCopy(File src, File dst) throws IOException {
try (FileChannel in = new FileInputStream(src).getChannel();
FileChannel out = new FileOutputStream(dst).getChannel()) {
in.transferTo(0, in.size(), out); // 内核级数据迁移
}
}
⚠ 注意:
• Windows 上部分版本 fallback 到普通拷贝
• 源 Channel 必须是 FileChannel(即本地文件)
• 目标 Channel 需支持写入(如 FileOutputStream.getChannel())
别踩坑:这些操作会拖慢速度
- 在循环内反复创建 byte[] 数组(应复用)
- 用
available()判断是否读完(不可靠,不适用于网络或管道) - 忽略异常后继续执行(可能导致静默截断)
- 未设置合适的缓冲区大小(太小 → 调用多;太大 → 浪费内存,缓存局部性下降)
不复杂但容易忽略:8KB 是多数场景下的甜点缓冲尺寸,兼顾 CPU、内存与磁盘块对齐。真要极致,可按存储介质(SSD/HDD)微调,但提升已不明显。











