Как скопировать файл с Java

Как скопировать файл с Java

1. обзор

В этой статье мы рассмотрим распространенные способы копирования файлов на Java.

Сначала мы будем использовать стандартные APIIO иNIO.2, а также две внешние библиотеки:commons-io иguava.

2. IO API (до JDK7)

Прежде всего,tocopy a file with java.io API, we’re required to open a stream, loop through the content and write it out to another stream:

@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 has improved its core APIs and we have a simpler way of copying files using NIO.2 API.

3. NIO.2 API (JDK7)

ИспользованиеNIO.2 может значительно повысить производительность копирования файлов, посколькуNIO.2 использует точки входа в систему более низкого уровня.

Давайте подробнее рассмотрим, как работает метод Files.copy().

Методcopy() дает нам возможность указать необязательный аргумент, представляющий параметр копирования. By default, copying files and directories won’t overwrite existing ones, nor will it copy file attributes.

Это поведение можно изменить, используя следующие параметры копирования:

  • REPLACE_EXISTING – заменить файл, если он существует

  • COPY_ATTRIBUTES – копирует метаданные в новый файл

  • NOFOLLOW_LINKS – не должен переходить по символическим ссылкам

КлассNIO.2 Files предоставляет набор перегруженных методовcopy() для копирования файлов и каталогов в файловой системе.

Давайте посмотрим на пример использованияcopy() с двумя аргументамиPath:

@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)));
}

Обратите внимание, чтоdirectory copies are shallow означает, что файлы и подкаталоги в каталоге не копируются.

4. Apache Commons IO

Другой распространенный способ копирования файла с помощью Java - использование библиотекиcommons-io.

Во-первых, нам нужно добавить зависимость:


    commons-io
    commons-io
    2.6

Последнюю версию можно скачать сMaven Central.

Затем, чтобы скопировать файл, нам просто нужно использоватьcopyFile() method defined in the FileUtils class.. Метод принимает исходный и целевой файл.

Давайте посмотрим на тест JUnit с использованием методаcopyFile():

@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. гуайява

Наконец, мы взглянем на библиотеку Google Guava.

Опять же, если мы хотим использовать Guava,, нам нужно включить зависимость:


    com.google.guava
    guava
    23.0

Последнюю версию можно найтиon 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.

Полную реализацию этой статьи можно найтиover on Github.