首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java IO 遞歸實戰:目錄樹完整拷貝 (含子目錄、文件字節流拷貝)

     編輯:Java 綜合教學

需求:完整複製目錄結構

將源目錄 f:/Exercises 遞歸複製到目標目錄 f:/book,保持子目錄層級與文件內容完全一致。

核心遞歸算法

public static void copyFile(File src, File dest) {
    if (src.isDirectory()) {
        // 1. 創建目標目錄
        dest.mkdir();                            // 若父目錄不存在會失敗,生產建議 mkdirs()
        // 2. 遍歷子項遞歸
        File[] children = src.listFiles();
        if (children != null) {
            for (File child : children) {
                copyFile(child, new File(dest, child.getName()));
            }
        }
    } else if (src.isFile()) {
        // 3. 文件拷貝:創建目標文件 + 字節流拷貝內容
        try {
            dest.createNewFile();                // 確保文件存在
            copyData(src.getAbsolutePath(), dest.getAbsolutePath());
        } catch (IOException e) { e.printStackTrace(); }
    }
}

字節流拷貝核心:copyData()

public static void copyData(String srcPath, String destPath) {
    try (FileInputStream fis = new FileInputStream(srcPath);
         FileOutputStream fos = new FileOutputStream(destPath)) {
        byte[] buffer = new byte[1024];          // 1KB 緩衝區
        int len;
        while ((len = fis.read(buffer)) != -1) { // 讀取到緩衝區
            fos.write(buffer, 0, len);           // 寫入實際讀取長度
        }
    } catch (IOException e) { e.printStackTrace(); }
}

關鍵點:

  • try-with-resources 自動關閉流,無需 finally
  • fis.read(buffer) 返回實際讀取字節數,-1 表示 EOF
  • fos.write(buffer, 0, len) 僅寫入有效數據,避免殘留垃圾字節

完整可運行主類

public class DirectoryCopier {
    public static void main(String[] args) {
        File src = new File("f:/Exercises");
        File dest = new File("f:/book");
        if (!src.exists()) {
            System.err.println("源目錄不存在: " + src.getAbsolutePath());
            return;
        }
        long start = System.currentTimeMillis();
        copyFile(src, dest);
        System.out.printf("拷貝完成,耗時 %d ms%n", System.currentTimeMillis() - start);
    }
    // copyFile() 與 copyData() 方法放此處
}

生產級增強建議

缺陷增強方案
mkdir() 父目錄不存在失敗改用 dest.mkdirs() 遞歸創建
無進度反饋引入 ProgressMonitor 或回調接口報告已拷貝字節/文件數
大文件內存壓力緩衝區調大至 64KB-256KB;或用 FileChannel.transferTo() 零拷貝
符號鏈接/特殊文件Files.walkFileTree() (NIO.2) 可精確控制訪問選項
權限保留NIO.2 Files.copy(src, dest, StandardCopyOption.COPY_ATTRIBUTES)
併發拷貝目錄級並行:ForkJoinPool 提交子目錄任務
異常處理粗糙自定義 CopyException 封裝路徑、原因,上層統一處理

NIO.2 一行代碼實現 (Java 7+)

Files.walkFileTree(src.toPath(), new SimpleFileVisitor() {
    @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        Path target = dest.toPath().resolve(src.toPath().relativize(dir));
        Files.createDirectories(target); return FileVisitResult.CONTINUE;
    }
    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Path target = dest.toPath().resolve(src.toPath().relativize(file));
        Files.copy(file, target, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
        return FileVisitResult.CONTINUE;
    }
});

優勢: 自動處理符號鏈接、權限、原子性替換、異常傳播,代碼更健壯。

總結

遞歸 + 字節流是理解文件系統操作的基礎範式。掌握 File.listFiles()、mkdirs()、createNewFile()、緩衝流讀寫循環,能應對絕大多數文件拷貝場景。生產環境強烈建議升級至 NIO.2 Files.walkFileTree() 或成熟工具庫,獲得更強的健壯性與性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved