当前位置: 首页 > news >正文

Java 实现目录递归拷贝

Java 实现目录递归拷贝

目录递归拷贝是指将一个目录及其所有子目录和文件完整复制到另一个位置。下面我将详细介绍如何使用 Java 的 File 类实现这一功能,并提供优化版本(NIO.2)和常见问题解决方案。


1. 基于 File 类的递归拷贝实现

核心思路

  1. 如果是文件 → 直接拷贝

  2. 如果是目录 → 创建目标目录 → 递归拷贝其内容

完整代码实现

java

import java.io.*;public class DirectoryCopy {public static void main(String[] args) {File srcDir = new File("C:/source");File destDir = new File("C:/destination");copyDirectory(srcDir, destDir);}public static void copyDirectory(File source, File target) throws IOException {if (!target.exists()) {target.mkdirs(); // 创建目标目录}for (File file : source.listFiles()) {File destFile = new File(target, file.getName());if (file.isDirectory()) {copyDirectory(file, destFile); // 递归拷贝子目录} else {copyFile(file, destFile); // 拷贝文件}}}private static void copyFile(File source, File dest) throws IOException {try (InputStream in = new FileInputStream(source);OutputStream out = new FileOutputStream(dest)) {byte[] buffer = new byte[1024];int length;while ((length = in.read(buffer)) > 0) {out.write(buffer, 0, length);}}}
}

2. 使用 NIO.2(Java 7+ 推荐)

NIO.2 提供了更简洁高效的 API(Files.copy()):

java

import java.nio.file.*;public class NioDirectoryCopy {public static void main(String[] args) throws IOException {Path source = Paths.get("C:/source");Path target = Paths.get("C:/destination");copyDirectory(source, target);}public static void copyDirectory(Path source, Path target) throws IOException {Files.walkFileTree(source, new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {Path relativePath = source.relativize(dir);Path destPath = target.resolve(relativePath);Files.createDirectories(destPath); // 创建目标目录return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Path relativePath = source.relativize(file);Path destPath = target.resolve(relativePath);Files.copy(file, destPath, StandardCopyOption.REPLACE_EXISTING);return FileVisitResult.CONTINUE;}});}
}

优势

  • 自动处理符号链接

  • 支持原子操作和文件属性保留

  • 更简洁的异常处理


3. 关键问题与解决方案

问题1:文件已存在

  • 解决:添加覆盖选项

    java

// File 类方式
if (destFile.exists()) destFile.delete();// NIO 方式
Files.copy(file, destPath, StandardCopyOption.REPLACE_EXISTING);

问题2:大文件拷贝性能优化

  • 解决:使用缓冲流(Buffer)或 NIO 的 FileChannel

    java

// 使用 FileChannel(零拷贝技术)
try (FileChannel inChannel = new FileInputStream(source).getChannel();FileChannel outChannel = new FileOutputStream(dest).getChannel()) {inChannel.transferTo(0, inChannel.size(), outChannel);
}

问题3:权限保留

  • NIO 解决方案

    java

Files.copy(file, destPath, StandardCopyOption.COPY_ATTRIBUTES);

4. 性能对比

方法适用场景优点缺点
File + 字节流Java 6 及以下版本兼容性好代码冗长,性能较低
Files.copy()Java 7+ 常规需求简洁高效不兼容旧 Java 版本
FileChannel大文件拷贝零拷贝,性能最佳代码稍复杂

5. 递归拷贝的注意事项

  1. 符号链接:NIO.2 的 Files.walkFileTree() 会自动处理,传统方式需要额外判断

  2. 异常处理:确保关闭流资源(用 try-with-resources)

  3. 内存管理:拷贝超大文件时避免一次性读取全部内容


6. 扩展练习

  1. 添加进度显示:在拷贝时打印已完成文件数/总文件数

  2. 实现断点续传:记录已拷贝文件,程序重启后跳过已处理部分

  3. 多线程拷贝:对子目录使用线程池加速(注意线程安全)

相关文章:

  • django之账号管理功能
  • 用Python做有趣的AI项目1:用 TensorFlow 实现图像分类(识别猫、狗、汽车等)
  • lvgl 实现横向滑动,并且捕获最中间那个元素
  • SpringCloud微服务架构
  • 基于先进MCU的机器人运动控制系统设计:理论、实践与前沿技术
  • VS BUG(6) LINK : fatal error LNK1158: 无法运行“rc.exe”
  • 用 C 语言实现通用的冒泡排序算法
  • UNO Less-to-More Generalization: 通过上下文生成解锁更多可控性
  • 使用UltraSigma给普源RIGOL示波器截图的方法
  • 基于 Python 的自然语言处理系列(86):DPO(Direct Preference Optimization)原理与实战
  • 【信息系统项目管理师】高分论文:论质量管理和进度管理(智慧旅游平台建设项目)
  • HBase协处理器深度解析:原理、实现与最佳实践
  • 基于FFmpeg命令行的实时图像处理与RTSP推流解决方案
  • 使用java代码注册onloyoffice账号 || 注册onloyoffice账号
  • vue中 vue.config.js反向代理
  • 计算机网络 | 应用层(3)-- 因特网中的电子邮件
  • 使用银行卡二要素API让支付更加安心
  • 北斗导航 | Transformer增强BiLSTM网络的GNSS伪距观测量误差探测
  • B. And It‘s Non-Zero
  • 提示词的神奇魔力——如何通过它改变AI的输出
  • 新任浙江省委常委、组织部长杨荫凯到嘉兴南湖瞻仰红船
  • “世纪火种”嘉年华启动,69家单位加入阅读“朋友圈”
  • 新闻1+1丨应对外部冲击,中央政治局会议释放哪些信号?
  • 证监会发布上市公司信披豁免规定:明确两类豁免范围、规定三种豁免方式
  • 临沂文旅集团被诉侵权,原告每年三百余起类案
  • 咖啡与乳腺健康之间,究竟有着怎样的复杂关系?