Java java.nio.file.Files copy() 方法详解
java.nio.file.Files.copy()
是 Java NIO (New Input/Output) 包中提供的一个实用方法,用于在文件系统之间复制文件或目录。这个方法提供了比传统 java.io
包更高效和灵活的文件操作能力。
方法重载
Files.copy()
方法有三个主要的重载形式:
从输入流复制到文件
public static long copy(InputStream in, Path target, CopyOption... options) throws IOException
从文件复制到输出流
public static long copy(Path source, OutputStream out) throws IOException
文件到文件的复制
public static Path copy(Path source, Path target, CopyOption... options) throws IOException
参数详解
输入参数
- InputStream in: 要复制的输入流
- Path source: 源文件路径
- Path target: 目标文件路径
- OutputStream out: 要写入的输出流
- CopyOption... options: 可选的复制选项
CopyOption 选项
常用的 CopyOption
包括:
StandardCopyOption.REPLACE_EXISTING
: 如果目标文件已存在,则替换它StandardCopyOption.COPY_ATTRIBUTES
: 复制文件属性到新文件LinkOption.NOFOLLOW_LINKS
: 不跟随符号链接
返回值
- 对于流到文件的复制:返回复制的字节数
- 对于文件到文件的复制:返回目标文件路径
- 对于文件到流的复制:返回复制的字节数
使用示例
基本文件复制
实例
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
try {
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println("文件复制成功");
} catch (IOException e) {
System.err.println("复制失败: " + e.getMessage());
}
Path target = Paths.get("target.txt");
try {
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
System.out.println("文件复制成功");
} catch (IOException e) {
System.err.println("复制失败: " + e.getMessage());
}
带属性的文件复制
实例
Path source = Paths.get("source.txt");
Path target = Paths.get("target.txt");
try {
Files.copy(source, target,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
System.out.println("文件及属性复制成功");
} catch (IOException e) {
System.err.println("复制失败: " + e.getMessage());
}
Path target = Paths.get("target.txt");
try {
Files.copy(source, target,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES);
System.out.println("文件及属性复制成功");
} catch (IOException e) {
System.err.println("复制失败: " + e.getMessage());
}
输入流到文件的复制
实例
try (InputStream in = new URL("http://example.com/file.txt").openStream()) {
Path target = Paths.get("downloaded.txt");
long bytesCopied = Files.copy(in, target);
System.out.println("下载完成,复制了 " + bytesCopied + " 字节");
} catch (IOException e) {
System.err.println("下载失败: " + e.getMessage());
}
Path target = Paths.get("downloaded.txt");
long bytesCopied = Files.copy(in, target);
System.out.println("下载完成,复制了 " + bytesCopied + " 字节");
} catch (IOException e) {
System.err.println("下载失败: " + e.getMessage());
}
注意事项
- 目录复制:
Files.copy()
方法默认不会递归复制目录内容,只会复制空目录 - 符号链接: 默认会跟随符号链接,除非指定
LinkOption.NOFOLLOW_LINKS
- 原子性: 文件复制操作不是原子的,可能在操作过程中失败
- 性能: 对于大文件,NIO 的复制通常比传统 IO 更高效
- 异常处理: 必须处理可能抛出的
IOException
与传统 IO 的比较
特性 | NIO Files.copy() | 传统 IO (FileInputStream/FileOutputStream) |
---|---|---|
性能 | 更高 | 较低 |
功能丰富度 | 更丰富 | 基本 |
异常处理 | 更简洁 | 较繁琐 |
符号链接处理 | 支持 | 不支持 |
文件属性复制 | 支持 | 不支持 |
最佳实践
- 对于简单的文件复制,使用最基本的
Files.copy()
形式 - 需要保留文件属性时,添加
COPY_ATTRIBUTES
选项 - 处理可能已存在的目标文件时,使用
REPLACE_EXISTING
- 对于大文件,考虑使用
Files.copy()
而非传统 IO 方法 - 总是使用 try-with-resources 处理流资源
点我分享笔记