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

Java File 文件操作大全:從基礎 CRUD 到目錄遞歸與工具類封裝

     編輯:Java 程式設計入門

一、文件/目錄存在性與類型判斷

File file = new File("/path/to/file.txt");

// 存在性
boolean exists = file.exists();

// 類型判斷
boolean isFile = file.isFile();       // 是否文件
boolean isDir = file.isDirectory();   // 是否目錄

二、創建文件與目錄

// 創建文件(不存在時)
File file = new File("/path/to/new.txt");
if (!file.exists()) {
    try {
        file.createNewFile(); // 返回 boolean,原子操作
    } catch (IOException e) { e.printStackTrace(); }
}

// 創建目錄
File dir = new File("/path/to/dir");
dir.mkdir();    // 單級目錄,父目錄必須存在
dir.mkdirs();   // 多級目錄,自動創建父目錄(推薦)

三、遍歷目錄內容

File dir = new File("/path/to/dir");

// 僅獲取名稱(效率較高)
String[] names = dir.list();
// 或帶過濾器
String[] txtFiles = dir.list((d, name) -> name.endsWith(".txt"));

// 獲取 File 對象(便於後續操作)
File[] files = dir.listFiles();
File[] subDirs = dir.listFiles(File::isDirectory);

四、刪除操作

// 簡單刪除(目錄必須為空)
file.delete();           // 立即刪除
file.deleteOnExit();     // JVM 退出時刪除

// 遞歸刪除非空目錄
public static void deleteRecursive(File file) throws IOException {
    if (!file.exists()) throw new FileNotFoundException(file.getAbsolutePath());
    
    if (file.isDirectory()) {
        File[] children = file.listFiles();
        if (children != null) {
            for (File child : children) deleteRecursive(child);
        }
    }
    if (!file.delete()) throw new IOException("刪除失敗: " + file);
}

五、重命名與移動

File src = new File("/path/src.txt");
File dest = new File("/path/dest.txt");
// 同目錄下重命名,跨目錄則為移動
boolean success = src.renameTo(dest); // 跨文件系統可能失敗

六、文件複製(File 類無內置方法,需手動實現)

6.1 基礎字節流複製

private static void copyStream(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[8192]; // 8KB 緩衝區
    int len;
    while ((len = in.read(buffer)) != -1) {
        out.write(buffer, 0, len);
    }
}

6.2 完整文件複製(含覆蓋控制)

public static void copyFile(File src, File dest, boolean overwrite) throws IOException {
    if (!src.exists()) throw new FileNotFoundException("源文件不存在: " + src);
    if (!src.isFile()) throw new IOException("源不是文件: " + src);
    
    if (dest.exists()) {
        if (!overwrite) return; // 不覆蓋直接返回
        if (!dest.delete()) throw new IOException("無法刪除目標文件: " + dest);
    }
    
    try (FileInputStream fis = new FileInputStream(src);
         FileOutputStream fos = new FileOutputStream(dest);
         BufferedInputStream bis = new BufferedInputStream(fis);
         BufferedOutputStream bos = new BufferedOutputStream(fos)) {
        copyStream(bis, bos);
    }
}

6.3 目錄遞歸複製

public static void copyDirectory(File srcDir, File destDir) throws IOException {
    if (!srcDir.exists()) throw new FileNotFoundException("源目錄不存在: " + srcDir);
    if (!srcDir.isDirectory()) throw new IOException("源不是目錄: " + srcDir);
    
    if (!destDir.exists() && !destDir.mkdirs()) {
        throw new IOException("無法創建目標目錄: " + destDir);
    }
    
    File[] children = srcDir.listFiles();
    if (children != null) {
        for (File child : children) {
            File target = new File(destDir, child.getName());
            if (child.isDirectory()) {
                copyDirectory(child, target);
            } else {
                copyFile(child, target, true);
            }
        }
    }
}

七、路徑與屬性獲取

File f = new File("/Users/name/file.txt");
f.getAbsolutePath(); // 絕對路徑
f.getParent();       // 父目錄路徑
f.getName();         // 文件名
f.getPath();         // 構造時的路徑
f.length();          // 文件大小(字節),目錄返回 0 或不確定值

八、目錄大小遞歸統計

public static long getDirectorySize(File dir) {
    if (!dir.exists()) throw new FileNotFoundException(dir.getAbsolutePath());
    if (dir.isFile()) return dir.length();
    
    long size = 0;
    File[] files = dir.listFiles();
    if (files != null) {
        for (File f : files) size += getDirectorySize(f);
    }
    return size;
}

// 友好格式化輸出
public static String formatSize(long bytes) {
    if (bytes < 1024) return bytes + " B";
    int z = (int) (Math.log(bytes) / Math.log(1024));
    String[] units = {"B", "KB", "MB", "GB", "TB"};
    return String.format("%.1f %s", bytes / Math.pow(1024, z), units[z]);
}

九、FileUtil 完整工具類(生產就緒版)

public final class FileUtil {
    private FileUtil() {} // 工具類防實例化

    // 刪除、複製、大小統計、格式化等靜態方法...
    // 建議補全:讀取文本、寫入文本、MD5 校驗、臨時文件創建等
    
    // 關鍵改進點:
    // 1. 統一拋出受檢異常或自定義 RuntimeException
    // 2. 使用 try-with-resources 確保流關閉
    // 3. 複制大文件時考慮 NIO 零拷貝:Files.copy(src, dest, REPLACE_EXISTING)
    // 4. 遞歸操作防止棧溢出(深度極大時改用棧/隊列迭代)
}

十、現代化替代:Java NIO.2 (JDK 7+)

java.nio.file.Files 和 Path 提供更豐富、線程安全、支持符號鏈接的 API:

Path src = Paths.get("/src/file.txt");
Path dest = Paths.get("/dest/file.txt");

// 複製(原子性選項、屬性複製)
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING, 
           StandardCopyOption.COPY_ATTRIBUTES);

// 遞歸刪除
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
    public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
        Files.delete(f); return FileVisitResult.CONTINUE;
    }
    public FileVisitResult postVisitDirectory(Path d, IOException e) throws IOException {
        Files.delete(d); return FileVisitResult.CONTINUE;
    }
});

// 遍歷
Files.list(dir).filter(p -> p.toString().endsWith(".log")).forEach(System.out::println);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved