1. 概述
在本文中,我们将介绍在Java中复制文件的常用方法。
首先,我们将使用标准IO和NIO 2 API,以及两个外部库:commons-io和guava。
2. IO API(JDK 7之前)
首先,要使用java.io API复制文件,我们需要打开一个流,遍历内容并将其写出到另一个流:
@Test
public void givenIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException {
File copied = new File("src/test/resources/copiedWithIo.txt");
try (InputStream in = new BufferedInputStream(new FileInputStream(original)); OutputStream out = new BufferedOutputStream(
new FileOutputStream(copied))) {
byte[] buffer = new byte[1024];
int lengthRead;
while ((lengthRead = in.read(buffer)) > 0) {
out.write(buffer, 0, lengthRead);
out.flush();
}
}
assertThat(copied).exists();
assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath())));
}
实现这样的基本功能需要做很多工作。
幸运的是,Java改进了其核心API,并且我们可以使用NIO 2 API更简单地复制文件。
3. NIO 2 API(JDK 7)
使用NIO 2可以显著提高文件复制性能,因为NIO 2使用较低级别的系统入口点。
让我们仔细看看Files. copy()方法是如何工作的。
copy()方法使我们能够指定表示复制选项的可选参数。默认情况下,复制文件和目录不会覆盖现有的,也不会复制文件属性。
可以使用以下选项更改此行为:
- REPLACE_EXISTING:替换文件(如果存在)
- COPY_ATTRIBUTES:将元数据到复制新文件
- NOFOLLOW_LINKS:不应遵循符号链接
NIO 2Files类提供了一组重载的copy()方法,用于在文件系统中复制文件和目录。
让我们看一个使用带有两个Path参数的copy()的例子:
@Test
public void givenNIO2_whenCopied_thenCopyExistsWithSameContents() throws IOException {
Path copied = Paths.get("src/test/resources/copiedWithNio.txt");
Path originalPath = original.toPath();
Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING);
assertThat(copied).exists();
assertThat(Files.readAllLines(originalPath).equals(Files.readAllLines(copied)));
}
请注意,目录副本是浅的,这意味着目录中的文件和子目录不会被复制。
4. Apache Commons IO
使用Java复制文件的另一种常见方法是使用commons-io库。
首先,我们需要添加依赖:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
最新版本可以从Maven Central下载。
然后,要复制文件,我们只需要使用FileUtils类中定义的copyFile()方法。该方法接收源文件和目标文件。
让我们看一下使用copyFile()方法的JUnit测试:
@Test
public void givenCommonsIoAPI_whenCopied_thenCopyExistsWithSameContents() throws IOException {
File copied = new File("src/test/resources/copiedWithApacheCommons.txt");
FileUtils.copyFile(original, copied);
assertThat(copied).exists();
assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath())));
}
5. Guava
最后,我们将看一下Google的Guava库。
同样,如果我们想使用Guava,我们需要包含依赖项:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
最新版本可以在Maven Central上找到。
这是Guava复制文件的方式:
@Test
public void givenGuava_whenCopied_thenCopyExistsWithSameContents() throws IOException {
File copied = new File("src/test/resources/copiedWithGuava.txt");
com.google.common.io.Files.copy(original, copied);
assertThat(copied).exists();
assertThat(Files.readAllLines(original.toPath()).equals(Files.readAllLines(copied.toPath())));
}
6. 总结
在本文中,我们探讨了在Java中复制文件的最常见方法。
与往常一样,本教程的完整源代码可在GitHub上获得。
Show Disqus Comments
Post Directory
扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章