java文件拷贝有三种主流方式:小文件用fileinputstream+fileoutputstream配8kb缓冲区并try-with-resources;大文件或简洁需求用nio files.copy()一行实现;需进度监控则手动循环读写并累计字节数,配合回调与原子提交保障可靠性。

Java 中实现文件拷贝,核心在于选择合适的 IO 模式:小文件可用 FileInputStream + FileOutputStream 配合字节数组缓冲;大文件或追求简洁可直接用 NIO 的 Files.copy();若需进度监控或断点续传,则需手动控制读写流程并统计已传输字节。
基础字节流拷贝(兼容 JDK 7 以下)
适用于大多数普通场景,可控性强,内存占用可控。关键点是使用 8KB(8192 字节)左右的缓冲区,避免单字节读写性能极低。
- 创建输入流和输出流时,务必使用
try-with-resources自动关闭,防止句柄泄漏 - 每次
read(byte[])返回实际读取字节数,必须用该值作为write(byte[], int, int)的长度参数,不可直接写整个缓冲区 - 示例片段:
byte[] buf = new byte[8192]; int len; while ((len = in.read(buf)) != -1) { out.write(buf, 0, len); }
NIO Files.copy 快速实现(推荐 JDK 7+)
一行代码完成拷贝,底层自动优化,支持复制到 Path、OutputStream 或从 InputStream 读取,且能处理符号链接与属性(需指定选项)。
- 最简调用:
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING) - 如需保留文件属性(修改时间、权限等),追加
StandardCopyOption.COPY_ATTRIBUTES - 注意:目标目录必须存在,否则抛
NoSuchFileException;可用Files.createDirectories(target.getParent())预创建
带进度回调的可控拷贝(适合大文件上传/下载)
当需要实时反馈拷贝进度(例如 Swing 进度条或日志打印),就不能依赖封装好的方法,而要手动循环读写并累计字节数。
- 定义回调接口,如
Consumer<long> progressCallback</long>,每写入一次就传入当前总字节数 - 在 while 循环内累加
total += len,并在合适时机(如每 100KB 或每秒)触发回调,避免高频更新拖慢主线程 - 建议配合
AtomicLong或同步块保护累计值,多线程环境下更安全
异常处理与健壮性增强
生产环境不能只捕获 Exception,要区分处理:路径问题、权限不足、磁盘满、中断等需不同响应策略。
-
IOException是主异常,包括文件不存在、无读写权限、设备忙等,应记录详细信息(如e.getMessage()和e.getStackTrace()) -
SecurityException多见于沙箱环境,需检查安全管理器策略 - 拷贝前建议先校验源文件是否存在且可读:
Files.isReadable(source) && Files.isRegularFile(source) - 目标路径建议预检查父目录是否可写:
Files.isDirectory(target.getParent()) && Files.isWritable(target.getParent())
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











