文章目录
- [364. Java IO API - 复制文件和目录](#364. Java IO API - 复制文件和目录)
-
-
- [✅ 1. 基本用法](#✅ 1. 基本用法)
- [⚙️ 2. 常用复制选项(CopyOption)](#⚙️ 2. 常用复制选项(CopyOption))
- [📁 3. 注意:目录复制不包含内容!](#📁 3. 注意:目录复制不包含内容!)
- [🔗 4. 关于符号链接的行为](#🔗 4. 关于符号链接的行为)
- [🧪 示例:完整文件复制流程](#🧪 示例:完整文件复制流程)
- [🔁 5. 从流中复制 / 到流中复制](#🔁 5. 从流中复制 / 到流中复制)
-
- [➡️ InputStream → File](#➡️ InputStream → File)
- [➡️ File → OutputStream](#➡️ File → OutputStream)
- [🚧 常见错误与建议](#🚧 常见错误与建议)
- [📌 小结](#📌 小结)
-
364. Java IO API - 复制文件和目录
在日常开发中,复制文件或目录是非常常见的需求。Java 提供了灵活且强大的 Files.copy() 方法来处理这些操作。
✅ 1. 基本用法
java
Files.copy(sourcePath, targetPath);
这行代码会尝试将 sourcePath 复制到 targetPath,但如果目标已存在,会抛出 FileAlreadyExistsException。
⚙️ 2. 常用复制选项(CopyOption)
你可以使用可变参数(varargs)形式传入多个选项:
java
Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
| 枚举常量 | 含义说明 |
|---|---|
REPLACE_EXISTING |
如果目标已存在则替换。对于符号链接,会复制"链接本身",而非其指向目标。 |
COPY_ATTRIBUTES |
尽量复制原文件的属性(如修改时间等)。平台支持情况可能不同。 |
NOFOLLOW_LINKS |
如果源是符号链接,仅复制链接本身,而不跟踪其目标。 |
📁 3. 注意:目录复制不包含内容!
虽然你可以复制一个目录:
java
Files.copy(Paths.get("docs"), Paths.get("docs_copy"));
但是这样复制的是空目录,原始目录中的子文件和子目录不会自动复制。
📌 如果你想复制整个目录结构,需要使用递归或第三方库(如 Apache Commons IO)。
🔗 4. 关于符号链接的行为
默认情况下,复制符号链接会复制它所指向的目标内容:
java
Files.copy(linkPath, copyPath); // 默认会"追踪"链接并复制目标
但如果你只想复制"链接本身":
java
Files.copy(linkPath, copyPath, NOFOLLOW_LINKS);
🧪 示例:完整文件复制流程
java
import java.nio.file.*;
import java.io.IOException;
import static java.nio.file.StandardCopyOption.*;
public class FileCopyDemo {
public static void main(String[] args) {
Path source = Paths.get("example.txt");
Path target = Paths.get("backup/example.txt");
try {
Files.copy(source, target, REPLACE_EXISTING, COPY_ATTRIBUTES);
System.out.println("✅ 文件复制成功!");
} catch (IOException e) {
System.err.println("❌ 复制失败:" + e.getMessage());
}
}
}
🔁 5. 从流中复制 / 到流中复制
除了 Path-to-Path 的复制,Files 类还支持以下操作:
➡️ InputStream → File
java
try (InputStream in = new FileInputStream("source.txt")) {
Files.copy(in, Paths.get("target.txt"), REPLACE_EXISTING);
}
➡️ File → OutputStream
java
try (OutputStream out = new FileOutputStream("output.txt")) {
Files.copy(Paths.get("source.txt"), out);
}
适用于文件上传、下载等场景!
🚧 常见错误与建议
| 问题场景 | 建议或说明 |
|---|---|
| 目标文件存在导致异常 | 使用 REPLACE_EXISTING |
| 复制目录却发现是空的 | 递归复制子文件或使用第三方库 |
| 权限不足导致 IOException | 检查文件读写权限 |
| 想保留时间戳等属性但没生效 | 尽量使用 COPY_ATTRIBUTES,并测试平台兼容性 |
📌 小结
| 操作类别 | 方法 |
|---|---|
| 文件复制 | Files.copy(Path, Path, ...) |
| 输入流 → 文件复制 | Files.copy(InputStream, Path) |
| 文件 → 输出流复制 | Files.copy(Path, OutputStream) |