文件操作是 Java 開發的「基本功」,但網上代碼片段良莠不齊、API 新舊混用、異常處理缺失。本文匯總 **70+ 生產級代碼片段**,按功能分類、採用 **NIO.2 為主**、覆蓋建立/刪除/複製/移動/遍歷/讀寫/屬性/壓縮/加密/監聽/剪貼板/註冊表/下載/對話框等全場景,可直接複製到專案工具類中使用。
Files.createDirectories(Paths.get("/data/logs/2024/01"));
Files.createFile(path, PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-r--r--")));
Files.createFile(path, StandardOpenOption.CREATE_NEW); // 存在拋 FileAlreadyExistsException
Files.deleteIfExists(path);
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;
}
});
Files.walkFileTree(dir, new SimpleFileVisitor() {
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file); return FileVisitResult.CONTINUE;
}
});
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;
}
});
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
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;
}
});
// 先複製
copyDirectory(src, dst);
// 再刪除源
deleteDirectory(src);
try (DirectoryStream stream = Files.newDirectoryStream(dir)) {
for (Path entry : stream) System.out.println(entry.getFileName());
}
try (DirectoryStream stream = Files.newDirectoryStream(dir, "*.log")) { ... }
try (Stream stream = Files.walk(root, 3)) {
stream.filter(Files::isRegularFile).forEach(System.out::println);
}
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;
}
});
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;
}
});
List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
String content = Files.readString(path, StandardCharsets.UTF_8);
try (Stream lines = Files.lines(path, StandardCharsets.UTF_8)) {
lines.filter(l -> l.contains("ERROR")).forEach(System.out::println);
}
Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Files.write(path, List.of("new line"), StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
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);
byte[] data = Files.readAllBytes(path);
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);
}
try (FileChannel ch = FileChannel.open(path, StandardOpenOption.READ)) {
MappedByteBuffer mbb = ch.map(FileChannel.MapMode.READ_ONLY, 0, ch.size());
// 直接操作 mbb
}
try (RandomAccessFile raf = new RandomAccessFile(path.toFile(), "rw")) {
raf.seek(100); raf.writeByte(0x42);
}
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
// attrs.size(), creationTime(), lastModifiedTime(), isDirectory(), isRegularFile(), isSymbolicLink()
Files.setPosixFilePermissions(path, PosixFilePermissions.fromString("rwxr-x---"));
Files.setAttribute(path, "dos:readonly", true); // Windows
// 或
path.toFile().setReadOnly();
String ext = path.getFileName().toString().substring(path.getFileName().toString().lastIndexOf('.') + 1);
String name = path.getFileName().toString();
Path parent = path.getParent();
Path newPath = path.resolveSibling(path.getFileName().toString().replaceFirst("\\.[^.]+$", "") + ".newExt");
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();
}
// 需 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;
}
});
}
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();
}
}
byte[] data = Files.readAllBytes(path);
for (int i = 0; i < data.length; i++) data[i] = (byte) ((data[i] + 100) % 256);
Files.write(encryptedPath, data);
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);
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;
}
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null);
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if (t != null && t.isDataFlavorSupported(DataFlavor.stringFlavor))
String text = (String) t.getTransferData(DataFlavor.stringFlavor);
Image img = ImageIO.read(imagePath.toFile());
TransferableImage ti = new TransferableImage(img);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ti, null);
JFileChooser fc = new JFileChooser(); fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) Path file = fc.getSelectedFile().toPath();
JFileChooser fc = new JFileChooser(); fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) Path dir = fc.getSelectedFile().toPath();
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);
}
// 需 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();
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+
long size = Files.walk(dir).filter(Files::isRegularFile).mapToLong(p -> { try { return Files.size(p); } catch (IOException e) { return 0L; } }).sum();
Path projectRoot = Paths.get("").toAbsolutePath().normalize();
Path resource = Paths.get(getClass().getResource("/config.yml").toURI());
Path tmp = Files.createTempFile("prefix-", ".tmp"); // 自動生成唯一名
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));
Files.write(merged, Files.readAllBytes(part1));
Files.write(merged, Files.readAllBytes(part2), StandardOpenOption.APPEND);
Files.newDirectoryStream(dir, "*.txt").forEach(p -> {
try { Files.move(p, p.resolveSibling(p.getFileName().toString().replace(".txt", ".log"))); }
catch (IOException e) { log.error("重命名失敗", e); }
});
String content = Files.readString(path, StandardCharsets.UTF_8).replace("old", "new");
Files.writeString(path, content, StandardCharsets.UTF_8);
Runtime.getRuntime().exec("assoc .mytype=MyAppFile");
Desktop.getDesktop().open(path.toFile()); // 文件/目錄
Desktop.getDesktop().browse(URI.create("https://example.com")); // 網頁
RegistryKey key = new RegistryKey(RootKey.HKEY_CURRENT_USER, "Software\\MyApp");
RegistryValue val = new RegistryValue("config", ValueType.REG_SZ, "data");
key.setValue(val);
// Windows .bat 包裝
Files.writeString(Paths.get("C:/app.bat"), "@echo off\njava -jar C:/app.jar\npause");
JPopupMenu menu = new JPopupMenu(); menu.add(new JMenuItem("複製")); menu.show(component, x, y);
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()));
}
(代碼結構同上,組合對應片段即可)
FileUtils、ZipUtils、CryptoUtils、ClipboardUtils 等工具類,**禁止在業務代碼中直接寫底層 IO**。