ZetCode

在 Java 中复制文件

上次修改时间:2024 年 3 月 6 日

在本文中,我们将展示如何在 Java 中复制文件。 我们使用内置类(包括 FileFileInputStreamFileOutputStreamFileChannelFiles)复制文件。

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

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

Bugs 文件

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

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

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

使用 FileInputStream & FileOutputStream 复制文件

使用 FileInputStreamFileOutputStream,我们创建用于读取和写入 File 的流。 如果找不到文件,则会抛出 FileNotFoundExceptionFile 是 Java 中文件或目录的表示形式。

Main.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

void main() throws IOException {

    var source = new File("bugs.txt");
    var dest = new File("bugs2.txt");

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

        byte[] buffer = new byte[1024];
        int length;

        while ((length = fis.read(buffer)) > 0) {

            fos.write(buffer, 0, length);
        }
    }
}

该示例使用 FileInputStreamFileOutputStreamFile 复制文件。

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

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

byte[] buffer = new byte[1024];

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

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

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

os.write(buffer, 0, length);

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

使用 Paths & Files 复制文件

下一个示例与前一个示例类似;它使用了更现代的 API。

Main.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

void main() throws IOException {

    var source = new File("bugs.txt");
    var dest = new File("bugs2.txt");

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

        byte[] buffer = new byte[1024];
        int length;

        while ((length = fis.read(buffer)) > 0) {

            fos.write(buffer, 0, length);
        }
    }
}

我们使用 PathsFiles 类复制文件。

var source = Paths.get("bugs.txt");
var dest = Paths.get("bugs2.txt");

我们从文件创建 Path 对象。

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

这些流是借助 Files 类创建的。

使用 FileChannel 复制文件

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

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

Main.java
import java.io.IOException;
import java.io.RandomAccessFile;

void main() throws IOException {

    try (var source = new RandomAccessFile("bugs.txt", "r");
            var dest = new RandomAccessFile("bugs2.txt", "rw")) {

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

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

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

try (var source = new RandomAccessFile("bugs.txt", "r");
        var dest = new RandomAccessFile("bugs2.txt", "rw")) {

创建读取模式的随机访问源文件,并创建读取/写入模式的随机访问文件。

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

我们使用 getChannel 从文件获取通道。

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

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

Files.copy 方法

Files.copy 方法提供了一种复制文件的简单方法。 如果目标文件存在,复制将失败,除非指定了 REPLACE_EXISTING 选项。 Files.copy 接受一个可选的第三个复制选项参数。

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

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

Main.java
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

void main() throws IOException {

    var source = new File("bugs.txt");
    var dest = new File("bugs2.txt");

    Files.copy(source.toPath(), dest.toPath(),
            StandardCopyOption.REPLACE_EXISTING);
}

该示例使用 Files.copy 复制文件。 如果目标文件已存在,则替换目标文件。

来源

Java 复制文件或目录 - 教程

在本文中,我们展示了如何在 Java 中复制文件的几种方法。

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。 我自 2007 年以来一直在撰写编程文章。迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有Java教程