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

Java IO 文件拷貝練習:遞歸遍歷、過濾 .java、重命名為 .txt

     編輯:Java 綜合教學

Java IO 文件拷貝練習:遞歸遍歷、過濾 .java、重命名為 .txt

需求:將指定目錄及其子目錄下所有 .java 文件拷貝到目標目錄,保持目錄結構,拷貝完成後將所有 .java 後綴改為 .txt。

核心思路

  1. 遞歸遍歷:深度優先搜索源目錄。
  2. 文件過濾:file.isFile() && file.getName().endsWith(".java")。
  3. 緩衝流拷貝:BufferedInputStream/BufferedOutputStream,8KB 緩衝區。
  4. 目錄鏡像:目標目錄按相對路徑創建對應子目錄。
  5. 空目錄剪枝:若某目錄下無 .java 文件(含遞歸),則不創建對應目標目錄。
  6. 後綴批量重命名:拷貝完成後再次遍歷目標目錄,renameTo() 修改後綴,處理同名衝突。

完整代碼實現

import java.io.*;
import java.util.*;

public class JavaFileCopyRename {

    public static void main(String[] args) throws IOException {
        File srcDir = new File("E:\\IO流");
        File destDir = new File("E:\\IO");
        copyJavaFiles(srcDir, destDir);
        renameJavaToTxt(destDir);
        System.out.println("拷貝並重命名完成!");
    }

    /** 遞歸拷貝 .java 文件 */
    private static void copy(File src, File dest) throws IOException {
        File[] files = src.listFiles();
        if (files == null) return;

        for (File file : files) {
            if (file.isFile() && file.getName().endsWith(".java")) {
                // 確保目標目錄存在
                if (!dest.exists()) dest.mkdirs();
                // 緩衝流拷貝
                try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(dest, file.getName())))) {
                    byte[] buffer = new byte[8192];
                    int len;
                    while ((len = bis.read(buffer)) != -1) {
                        bos.write(buffer, 0, len);
                    }
                }
            } else if (file.isDirectory()) {
                // 剪枝:僅當子目錄包含 .java 文件時才遞歸
                if (containsJavaFile(file)) {
                    File newDest = new File(dest, file.getName());
                    copy(file, newDest);
                }
            }
        }
    }

    /** 判斷目錄樹中是否包含 .java 文件 */
    private static boolean containsJavaFile(File dir) {
        File[] files = dir.listFiles();
        if (files == null) return false;
        for (File file : files) {
            if (file.isFile() && file.getName().endsWith(".java")) return true;
            if (file.isDirectory() && containsJavaFile(file)) return true;
        }
        return false;
    }

    /** 批量將 .java 改為 .txt,處理同名衝突 */
    private static void renameJavaToTxt(File dir) throws IOException {
        File[] files = dir.listFiles();
        if (files == null) return;

        for (File file : files) {
            if (file.isFile() && file.getName().endsWith(".java")) {
                String newName = file.getName().replace(".java", ".txt");
                File newFile = new File(file.getParent(), newName);
                // 衝突處理:若目標文件已存在,先刪除
                if (newFile.exists()) newFile.delete();
                file.renameTo(newFile);
            } else if (file.isDirectory()) {
                renameJavaToTxt(file);
            }
        }
    }
}

關鍵點詳解

1. 緩衝流性能

BufferedInputStream/OutputStream 減少系統調用次數,8KB 緩衝區平衡內存與速度。使用 try-with-resources 自動關閉流。

2. 空目錄剪枝

containsJavaFile() 先序遍歷判斷,避免創建大量空目錄,節省磁盤空間與文件系統 inode。

3. 重命名衝突處理

同目錄下可能存在 A.java 和 A.txt(或拷貝後產生同名),renameTo() 在目標存在時返回 false,需先 delete() 再重命名。

4. 異常處理

生產代碼應捕獲 IOException,記錄失敗文件路徑,決定是繼續還是中止。

進階擴展

  • 使用 Files.walkFileTree (NIO.2) 替代手工遞歸,代碼更簡潔、支持訪問屬性過濾。
  • 引入 CountDownLatch + 線程池實現多線程並發拷貝,利用多核 CPU 與磁盤並行 IO。
  • 支持正則過濾、文件大小限制、增量同步(比對修改時間/MD5)。
  • 生成操作日誌(CSV/JSON),記錄源路徑、目標路徑、耗時、狀態。

此練習涵蓋了文件樹遍歷、流式拷貝、資源管理、衝突解決等 Java IO 核心技能,是文件處理類工具開發的基礎範式。

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