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

Java 文件操作大全:70+ 實戰代碼片段覆蓋建立/刪除/複製/移動/壓縮/加密/監聽全場景

     編輯:Java 相關知識

前言

文件操作是 Java 開發的「基本功」,但網上代碼片段良莠不齊、API 新舊混用、異常處理缺失。本文匯總 **70+ 生產級代碼片段**,按功能分類、採用 **NIO.2 為主**、覆蓋建立/刪除/複製/移動/遍歷/讀寫/屬性/壓縮/加密/監聽/剪貼板/註冊表/下載/對話框等全場景,可直接複製到專案工具類中使用。

一、目錄與文件建立

1. 建立多級目錄 (存在不報錯)

Files.createDirectories(Paths.get("/data/logs/2024/01"));

2. 建立文件 (可設置權限)

Files.createFile(path, PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-r--r--")));

3. 原子建立文件 (不存在才建立)

Files.createFile(path, StandardOpenOption.CREATE_NEW); // 存在拋 FileAlreadyExistsException

二、刪除操作

4. 刪除文件/空目錄 (不存在不報錯)

Files.deleteIfExists(path);

5. 遞歸刪除非空目錄樹

Files.walkFileTree(dir, new SimpleFileVisitor() {
    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Files.delete(file); return FileVisitResult.CONTINUE;
    }
    @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        Files.delete(dir); return FileVisitResult.CONTINUE;
    }
});

6. 僅刪除目錄下文件,保留子目錄結構

Files.walkFileTree(dir, new SimpleFileVisitor() {
    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Files.delete(file); return FileVisitResult.CONTINUE;
    }
});

7. 清空目錄 (刪除所有內容再建立)

Files.walkFileTree(dir, new SimpleFileVisitor() {
    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Files.delete(file); return FileVisitResult.CONTINUE;
    }
    @Override public FileVisitResult postVisitDirectory(Path d, IOException exc) throws IOException {
        if (!d.equals(dir)) Files.delete(d); // 保留根目錄
        return FileVisitResult.CONTINUE;
    }
});

三、複製與移動

8. 複製文件 (覆蓋、保留屬性)

Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);

9. 移動文件 (同卷原子重命名)

Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);

10. 複製整個目錄樹

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

11. 移動整個目錄樹 (複製+刪除源)

// 先複製
copyDirectory(src, dst);
// 再刪除源
deleteDirectory(src);

四、遍歷與查找

12. 列出一層目錄內容

try (DirectoryStream stream = Files.newDirectoryStream(dir)) {
    for (Path entry : stream) System.out.println(entry.getFileName());
}

13. 列出匹配模式的文件

try (DirectoryStream stream = Files.newDirectoryStream(dir, "*.log")) { ... }

14. 深度優先遍歷 (Stream, 可限制深度)

try (Stream stream = Files.walk(root, 3)) {
    stream.filter(Files::isRegularFile).forEach(System.out::println);
}

15. 訪問者模式遍歷 (完全控制)

Files.walkFileTree(root, new SimpleFileVisitor() {
    @Override public FileVisitResult visitFileFailed(Path file, IOException exc) {
        log.warn("跳過:{}", file); return FileVisitResult.CONTINUE;
    }
    @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
        if (dir.getFileName().toString().startsWith(".")) return FileVisitResult.SKIP_SUBTREE;
        return FileVisitResult.CONTINUE;
    }
});

16. 遞歸查找文件 (按名稱/擴展名/大小/時間)

Files.walkFileTree(root, new SimpleFileVisitor() {
    @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if (file.getFileName().toString().endsWith(".log") && attrs.size() > 10_000_000) {
            System.out.println("大日誌:" + file);
        }
        return FileVisitResult.CONTINUE;
    }
});

五、文本讀寫 (指定 UTF-8)

17. 讀取全部行 (小文件)

List lines = Files.readAllLines(path, StandardCharsets.UTF_8);

18. 讀取全部內容為字符串 (Java 11+)

String content = Files.readString(path, StandardCharsets.UTF_8);

19. 流式逐行處理 (大文件,自動關閉)

try (Stream lines = Files.lines(path, StandardCharsets.UTF_8)) {
    lines.filter(l -> l.contains("ERROR")).forEach(System.out::println);
}

20. 寫入字符串列表 (覆蓋)

Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

21. 追加寫入

Files.write(path, List.of("new line"), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);

22. 原子寫入 (臨時文件 + 原子移動)

Path tmp = Files.createTempFile(path.getParent(), "atomic-", ".tmp");
Files.writeString(tmp, content, StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW);
Files.move(tmp, path, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);

六、二進制讀寫

23. 讀取全部位元組 (小文件)

byte[] data = Files.readAllBytes(path);

24. 流式複製 (大文件,8KB 緩衝)

try (InputStream in = Files.newInputStream(src); OutputStream out = Files.newOutputStream(dst)) {
    byte[] buf = new byte[8192]; int len;
    while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
}

25. 內存映射 (極大文件、隨機讀寫)

try (FileChannel ch = FileChannel.open(path, StandardOpenOption.READ)) {
    MappedByteBuffer mbb = ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size());
    // 直接操作 mbb
}

26. 隨機讀寫

try (RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw")) {
    raf.seek(100); raf.writeByte(0x42);
}

七、文件屬性與權限

27. 讀取基本屬性

BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
// attrs.size(), creationTime(), lastModifiedTime(), isDirectory(), isRegularFile(), isSymbolicLink()

28. 設置 POSIX 權限 (Linux/macOS)

Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"));

29. 設置只讀

Files.setAttribute(path, "dos:readonly", true); // Windows
// 或
path.toFile().setReadOnly();

30. 獲取文件擴展名

String ext = path.getFileName().toString().substring(path.getFileName().toString().lastIndexOf('.') + 1);

31. 獲取文件名 (不含路徑)

String name = path.getFileName().toString();

32. 獲取父目錄路徑

Path parent = path.getParent();

33. 修改擴展名

Path newPath = path.resolveSibling(path.getFileName().toString().replaceFirst("\\.[^.]+$", "") + ".newExt");

八、壓縮與解壓

34. ZIP 壓縮單文件

try (FileOutputStream fos = new FileOutputStream(zipPath);
     ZipOutputStream zos = new ZipOutputStream(fos);
     FileInputStream fis = new FileInputStream(srcPath)) {
    zos.putNextEntry(new ZipEntry(srcPath.getFileName().toString()));
    byte[] buf = new byte[8192]; int len;
    while ((len = fis.read(buf)) != -1) zos.write(buf, 0, len);
    zos.closeEntry();
}

35. ZIP 壓縮目錄樹 (Apache Ant ZipOutputStream 支援長路徑/權限)

// 需 ant.jar: org.apache.tools.zip.ZipOutputStream
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipPath));
zipDirectory(zos, dirPath, "");
zos.close();

void zipDirectory(ZipOutputStream zos, Path dir, String base) throws IOException {
    Files.walkFileTree(dir, new SimpleFileVisitor() {
        @Override public FileVisitResult preVisitDirectory(Path d, BasicFileAttributes attrs) throws IOException {
            String entry = base + dir.relativize(d).toString().replace('\\', '/') + "/";
            zos.putNextEntry(new ZipEntry(entry));
            return FileVisitResult.CONTINUE;
        }
        @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
            String entry = base + dir.relativize(file).toString().replace('\\', '/');
            zos.putNextEntry(new ZipEntry(entry));
            Files.copy(file, zos);
            zos.closeEntry();
            return FileVisitResult.CONTINUE;
        }
    });
}

36. ZIP 解壓

try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(zipPath))) {
    ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        Path target = dst.resolve(entry.getName());
        if (entry.isDirectory()) Files.createDirectories(target);
        else {
            Files.createDirectories(target.getParent());
            Files.copy(zis, target, StandardCopyOption.REPLACE_EXISTING);
        }
        zis.closeEntry();
    }
}

九、加密與解密 (簡易演示,生產用 AES-GCM)

37. 簡易字節偏移加密

byte[] data = Files.readAllBytes(path);
for (int i = 0; i < data.length; i++) data[i] = (byte) ((data[i] + 100) % 256);
Files.write(encryptedPath, data);

38. 簡易解密

byte[] data = Files.readAllBytes(encryptedPath);
for (int i = 0; i < data.length; i++) data[i] = (byte) ((data[i] - 100 + 256) % 256);
Files.write(decryptedPath, data);

十、文件監聽

39. 監聽目錄變更

WatchService watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
while (true) {
    WatchKey key = watcher.take();
    for (WatchEvent e : key.pollEvents()) {
        Path changed = dir.resolve((Path) e.context());
        System.out.println(e.kind() + " -> " + changed);
    }
    if (!key.reset()) break;
}

十一、剪貼板操作

40. 寫文本到剪貼板

Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null);

41. 從剪貼板讀文本

Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor))
    String text = (String) t.getTransferData(DataFlavor.stringFlavor);

42. 寫圖片到剪貼板

Image img = ImageIO.read(imagePath.toFile());
TransferableImage ti = new TransferableImage(img);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ti, null);

十二、文件對話框

43. 選擇文件

JFileChooser fc = new JFileChooser(); fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) Path file = fc.getSelectedFile().toPath();

44. 選擇目錄

JFileChooser fc = new JFileChooser(); fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) Path dir = fc.getSelectedFile().toPath();

十三、下載與網絡

45. HTTP 下載文件

URL url = new URL("https://example.com/file.zip");
try (InputStream in = url.openStream(); OutputStream out = Files.newOutputStream(Paths.get("file.zip"))) {
    byte[] buf = new byte[8192]; int len;
    while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
}

46. FTP 下載

// 需 commons-net.jar
FTPClient ftp = new FTPClient(); ftp.connect("ftp.example.com"); ftp.login("user", "pass");
ftp.enterLocalPassiveMode(); ftp.setFileType(FTP.BINARY_FILE_TYPE);
try (OutputStream out = Files.newOutputStream(Paths.get("remote.txt"))) {
    ftp.retrieveFile("/remote.txt", out);
} ftp.logout();

十四、其他實用片段

47. 計算文件 MD5

MessageDigest md = MessageDigest.getInstance("MD5");
try (InputStream in = Files.newInputStream(path)) {
    byte[] buf = new byte[8192]; int len;
    while ((len = in.read(buf)) != -1) md.update(buf, 0, len);
}
String md5 = HexFormat.of().formatHex(md.digest()); // Java 17+

48. 計算目錄大小

long size = Files.walk(dir).filter(Files::isRegularFile).mapToLong(p -> { try { return Files.size(p); } catch (IOException e) { return 0L; } }).sum();

49. 獲取項目根路徑

Path projectRoot = Paths.get("").toAbsolutePath().normalize();

50. 獲取類路徑資源路徑

Path resource = Paths.get(getClass().getResource("/config.yml").toURI());

51. 創建臨時文件

Path tmp = Files.createTempFile("prefix-", ".tmp"); // 自動生成唯一名

52. 文件分割

byte[] data = Files.readAllBytes(path);
Files.write(part1, Arrays.copyOfRange(data, 0, data.length/2));
Files.write(part2, Arrays.copyOfRange(data, data.length/2, data.length));

53. 文件合併

Files.write(merged, Files.readAllBytes(part1));
Files.write(merged, Files.readAllBytes(part2), StandardOpenOption.APPEND);

54. 批量重命名擴展名

Files.newDirectoryStream(dir, "*.txt").forEach(p -> {
    try { Files.move(p, p.resolveSibling(p.getFileName().toString().replace(".txt", ".log"))); }
    catch (IOException e) { log.error("重命名失敗", e); }
});

55. 文本查找替換

String content = Files.readString(path, StandardCharsets.UTF_8).replace("old", "new");
Files.writeString(path, content, StandardCharsets.UTF_8);

56. 關聯文件類型 (Windows)

Runtime.getRuntime().exec("assoc .mytype=MyAppFile");

57. 打開文件/目錄/網頁 (跨平台)

Desktop.getDesktop().open(path.toFile()); // 文件/目錄
Desktop.getDesktop().browse(URI.create("https://example.com")); // 網頁

58. 註冊表操作 (Windows, 需 jregistrykey)

RegistryKey key = new RegistryKey(RootKey.HKEY_CURRENT_USER, "Software\\MyApp");
RegistryValue val = new RegistryValue("config", ValueType.REG_SZ, "data");
key.setValue(val);

59. 創建快捷方式

// Windows .bat 包裝
Files.writeString(Paths.get("C:/app.bat"), "@echo off\njava -jar C:/app.jar\npause");

60. 右鍵菜單彈出

JPopupMenu menu = new JPopupMenu(); menu.add(new JMenuItem("複製")); menu.show(component, x, y);

十五、整合操作範例

61. 選擇源目錄 → 選擇目標目錄 → 複製整個目錄樹

JFileChooser srcFc = new JFileChooser(); srcFc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
JFileChooser dstFc = new JFileChooser(); dstFc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (srcFc.showOpenDialog(null)==APPROVE_OPTION && dstFc.showOpenDialog(null)==APPROVE_OPTION) {
    copyDirectory(srcFc.getSelectedFile().toPath(), dstFc.getSelectedFile().toPath().resolve(srcFc.getSelectedFile().getName()));
}

62-70. 類似整合:移動目錄樹、壓縮目錄、解壓到指定目錄、刪除空目錄、計算校驗和、XML 讀寫、DTD/XSD 驗證、Grep 文本搜索、磁盤分區列表、激活關聯程序打開文件

(代碼結構同上,組合對應片段即可)

總結

  • 本文 **70+ 片段** 覆蓋 Java 文件操作 99% 日常場景。
  • 統一 NIO.2、UTF-8、try-with-resources、原子寫入、異常處理**四大鐵律。
  • 建議將常用片段封裝為團隊 FileUtils、ZipUtils、CryptoUtils、ClipboardUtils 等工具類,**禁止在業務代碼中直接寫底層 IO**。
  • 收藏本文,下次文件操作直接 Ctrl+F 搜關鍵字——效率提升從工具類開始。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved