原文:http://zetcode.com/java/copyfile/

在 Java 复制文件教程中,我们展示了如何使用 Java 复制文件。 我们复制具有内置类的文件,包括FileFileInputStreamFileOutputStreamFileChannelFiles。 我们还使用两个第三方库:Apache Commons IO 和 Google Guava。

文件复制是创建一个与现有文件具有相同内容的新文件。 文件移动正在将文件从一个位置传输到另一位置。

要复制的文件称为源文件,而新副本称为目标文件。

bugs 文件

在示例中,我们使用bugs.txt文件。

bugs.txt

  1. Assasin bug, Avondale spider, Backswimmer,
  2. Bamboo moth, Banana moth, Bed bug,
  3. Black cocroach, Blue moon, Bumble Bee,
  4. Carpenter Bee, Cattle tick, Cave Weta,
  5. Cicada, Cinnibar, Click beetle, Clothes moth,
  6. Codling moth, Centipede, Earwig, Eucalypt longhorn beetle,
  7. Field Grasshopper, Garden slug, Garden soldier,
  8. German cockroach, German wasp, Giant dragonfly,
  9. Giraffe weevil, Grass grub, Grass looper,
  10. Green planthopper, Green house spider, Gum emperor,
  11. Gum leaf skeletoniser, Hornet, Mealybug,
  12. Mites, Mole Cricket, Monarch butterfly,
  13. Mosquito, Silverfish, Wasp,
  14. Water boatman, Winged weta, Wolf spider,
  15. Yellow Jacket, Yellow Admiral

这是一个包含错误名称的简单文件。

使用FileInputStreamFileOutputStream复制文件

使用FileInputStreamFileOutputStream,我们创建用于读取和写入File的流。 找不到文件时,将引发FileNotFoundExceptionFile是 Java 中文件或目录的表示。

com/zetcode/CopyFileStream.java

  1. package com.zetcode;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. public class CopyFileStream {
  7. public static void main(String[] args) throws IOException {
  8. var source = new File("src/resources/bugs.txt");
  9. var dest = new File("src/resources/bugs2.txt");
  10. try (var fis = new FileInputStream(source);
  11. var fos = new FileOutputStream(dest)) {
  12. byte[] buffer = new byte[1024];
  13. int length;
  14. while ((length = fis.read(buffer)) > 0) {
  15. fos.write(buffer, 0, length);
  16. }
  17. }
  18. }
  19. }

本示例使用FileInputStreamFileOutputStreamFile复制文件。

  1. try (var fis = new FileInputStream(source);
  2. var fos = new FileOutputStream(dest)) {

我们创建FileInputStreamFileOutputStream的实例。 try-with-resources语句将自动关闭流。

  1. byte[] buffer = new byte[1024];

我们将复制 1024 个字节的文本块。 这样做是为了获得更好的性能。

  1. while ((length = is.read(buffer)) > 0) {

FileInputStreamread()方法从输入流中读取指定数量的字节,并将其存储到缓冲区数组中。 它返回读入缓冲区的字节总数,如果由于到达流的末尾而没有更多数据,则返回 -1。

  1. os.write(buffer, 0, length);

FileOutputStreamwrite()方法将存储在缓冲区中的字节写入输出流。 第一个参数是数据,第二个参数是数据中的起始偏移量,最后一个参数是要写入的字节数。

使用PathsFiles复制文件

下一个示例与上一个示例相似。 它使用了更现代的 API。

com/zetcode/CopyFileStream2.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.nio.file.Files;
  4. import java.nio.file.Paths;
  5. public class CopyFileStream2 {
  6. public static void main(String[] args) throws IOException {
  7. var source = Paths.get("src/resources/bugs.txt");
  8. var dest = Paths.get("src/resources/bugs2.txt");
  9. try (var fis = Files.newInputStream(source);
  10. var fos = Files.newOutputStream(dest)) {
  11. byte[] buffer = new byte[1024];
  12. int length;
  13. while ((length = fis.read(buffer)) > 0) {
  14. fos.write(buffer, 0, length);
  15. }
  16. }
  17. }
  18. }

我们使用PathsFiles类复制文件。

  1. var source = Paths.get("src/resources/bugs.txt");
  2. var dest = Paths.get("src/resources/bugs2.txt");

从文件中,我们创建Path对象。

  1. try (var fis = Files.newInputStream(source);
  2. var fos = Files.newOutputStream(dest)) {

流是在Files类的帮助下创建的。

使用FileChannel的复制文件

FileChannel是用于读取,写入,映射和操作文件的通道。 FileChannel是经典 Java IO 流 API 的替代方法。 它位于java.nio包中。

RandomAccessFile支持读取和写入随机访问文件。 随机访问意味着我们可以在文件中的任何位置读取或写入信息。

com/zetcode/CopyFileChannel.java

  1. package com.zetcode;
  2. import java.io.IOException;
  3. import java.io.RandomAccessFile;
  4. public class CopyFileChannel {
  5. public static void main(String[] args) throws IOException {
  6. var source = new RandomAccessFile("src/resources/bugs.txt", "r");
  7. var dest = new RandomAccessFile("src/resources/bugs2.txt", "rw");
  8. try (var sfc = source.getChannel();
  9. var dfc = dest.getChannel()) {
  10. dfc.transferFrom(sfc, 0, sfc.size());
  11. }
  12. }
  13. }

该示例使用FileChannel复制文本文件。

  1. var source = new RandomAccessFile("src/resources/bugs.txt", "r");

创建读取模式下的随机访问文件。

  1. var dest = new RandomAccessFile("src/resources/bugs2.txt", "rw");

创建一个处于读/写模式的随机访问文件。

  1. try (var sfc = source.getChannel();
  2. var dfc = dest.getChannel()) {

我们使用getChannel()从文件中获取频道。

  1. dfc.transferFrom(sfc, 0, sfc.size());

transferFrom()方法将字节从源通道传输到目标通道。 第一个参数是源通道,第二个参数是文件中传输的开始位置,第三个参数是要传输的最大字节数。

Files.copy复制文件

Java 7 引入了Files.copy()方法,该方法提供了一种复制文件的简便方法。 如果目标文件存在,则复制失败,除非指定了REPLACE_EXISTING选项。 Files.copy()采用可选的第三副本选项参数。

options参数可以包括以下任何一项:

  • REPLACE_EXISTING - 如果目标文件存在,则目标文件不是非空目录时,将替换目标文件。
  • COPY_ATTRIBUTES - 尝试将与此文件关联的文件属性复制到目标文件。
  • ATOMIC_MOVE - 移动文件。
  • NOFOLLOW_LINKS - 不遵循符号链接。

前三个选项在StandarCopyOption中可用; LinkOption中的最后一个。

com/zetcode/CopyFileJava7.java

  1. package com.zetcode;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.nio.file.Files;
  5. import java.nio.file.StandardCopyOption;
  6. public class CopyFileJava7 {
  7. public static void main(String[] args) throws IOException {
  8. var source = new File("src/resources/bugs.txt");
  9. var dest = new File("src/resources/bugs2.txt");
  10. Files.copy(source.toPath(), dest.toPath(),
  11. StandardCopyOption.REPLACE_EXISTING);
  12. }
  13. }

本示例使用Files.copy()复制文件。 如果目的地已经存在,它将替换目的地。

使用 Apache Commons IO 进行 Java 复制文件

Apache Commons IO 是一个工具库,可帮助开发 IO 功能。 它包含FileUtils.copyFile()方法来执行复制。 FileUtils.copyFile()将指定源文件的内容复制到指定目标文件中,并保留文件日期。 如果目标文件所在的目录不存在,则创建该目录。 如果目标文件存在,则此方法将覆盖它。

  1. <dependency>
  2. <groupId>commons-io</groupId>
  3. <artifactId>commons-io</artifactId>
  4. <version>2.5</version>
  5. </dependency>

对于此示例,我们需要commons-io工件。

com/zetcode/CopyFileApacheCommons.java

  1. package com.zetcode;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import org.apache.commons.io.FileUtils;
  5. public class CopyFileApacheCommons {
  6. public static void main(String[] args) throws IOException {
  7. var source = new File("src/main/resources/bugs.txt");
  8. var dest = new File("src/main/resources/bugs2.txt");
  9. FileUtils.copyFile(source, dest);
  10. }
  11. }

该示例使用 Apache Commons 的FileUtils.copyFile()复制文件。

用 Guava Java 复制文件

Google Guava 是 Java 通用库的开源集。 它包括用于复制文件的Files.copy()

  1. <dependency>
  2. <groupId>com.google.guava</groupId>
  3. <artifactId>guava</artifactId>
  4. <version>28.0-jre</version>
  5. </dependency>

我们使用 Guava 依赖。

com/zetcode/CopyFileGuava.java

  1. package com.zetcode;
  2. import com.google.common.io.Files;
  3. import java.io.File;
  4. import java.io.IOException;
  5. public class CopyFileGuava {
  6. public static void main(String[] args) throws IOException {
  7. var source = new File("src/main/resources/bugs.txt");
  8. var dest = new File("src/main/resources/bugs2.txt");
  9. Files.copy(source, dest);
  10. }
  11. }

该示例使用 Guava 的Files.copy()复制文件。

在本教程中,我们展示了几种用 Java 复制文件的方法。 我们使用了内置工具和第三方库。 您可能也对相关教程感兴趣: Java 文件教程Java 创建目录Java 文件大小用 Java 创建文件用 Java 读取文本文件Apache FileUtils教程Java 教程

列出所有 Java 教程