Копирование файла в Java

Копирование файла из одного места в другое в Java — это обычная задача, которую нам нужно выполнять в приложениях. В этом руководстве по Java мы рассмотрим различные способы копирования файла в Java.

Обратите внимание, что копирование файлов не является атомарной операцией — в случае ошибки ввода-вывода, потери питания, завершения процесса или других проблем операция копирования не будет завершена. Если нам нужно защититься от этих условий, мы должны использовать другую синхронизацию на уровне файлов.

Во всех приведенных примерах мы будем копировать содержимое testoriginal.txt в другой файл testcopied.txt. Имя и местоположение файлов можно заменить в любом из примеров.

1. Использование NIO Files.copy()

Класс Files находится в пакете java.nio.file. Он предоставляет статические методы, которые работают с файлами, каталогами или другими типами файлов.

  • По умолчанию копирование завершается неудачей, если целевой файл уже существует или является символической ссылкой, за исключением случая, когда исходный и целевой файлы являются одними и теми же файлами; в этом случае метод завершается без копирования файла.
  • Если файл является каталогом, то он создает пустой каталог в целевом местоположении(записи в каталоге не копируются).

Используйте одно или несколько перечислений CopyOption для управления тем, как должно выполняться копирование.

  • REPLACE_EXISTING: Любой существующий целевой файл будет заменен.
  • COPY_ATTRIBUTES: Копировать атрибуты файла из исходного в целевой файл.
  • NOFOLLOW_LINKS: Если файл является символической ссылкой, то копируется сама символическая ссылка, а не цель ссылки.
Path source = Paths.get("c:/temp/testoriginal.txt");Path target = Paths.get("c:/temp/testcopied.txt");Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);

2. Использование FileChannel.transferTo()

Если вам нравится класс FileChannel за его блестящую производительность, используйте этот метод. Ключевое преимущество здесь в том, что JVM использует доступ ОС к DMA(прямой доступ к памяти), если он присутствует.

При использовании этой технологии данные передаются напрямую с диска на шину, а затем к месту назначения, минуя любые цепи через ОЗУ или ЦП.

File fileToCopy = new File("c:/temp/testoriginal.txt");FileInputStream inputStream = new FileInputStream(fileToCopy);FileChannel inChannel = inputStream.getChannel();File newFile = new File("c:/temp/testcopied.txt");FileOutputStream outputStream = new FileOutputStream(newFile);FileChannel outChannel = outputStream.getChannel();inChannel.transferTo(0, fileToCopy.length(), outChannel);inputStream.close();outputStream.close();

3. Использование FileUtils Commons IO

Чтобы использовать Apache Commons IO, нам потребуется загрузить зависимость commons-io и включить ее в проект.

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency>

Для копирования одного файла в другой используйте один из следующих классов.

  • FileUtils – внутри себя он использует класс java.nio.file.Files, поэтому его использование эквивалентно использованию функции java.nio.file.Files.copy().
  • IOUtils – копирует байты из большого(более 2 ГБ) InputStream в OutputStream. Этот метод использует предоставленный буфер, поэтому нет необходимости использовать BufferedInputStream.
File fileToCopy = new File("c:/temp/testoriginal.txt");File newFile = new File("c:/temp/testcopied.txt");FileUtils.copyFile(fileToCopy, newFile);// ORIOUtils.copy(new FileInputStream(fileToCopy), new FileOutputStream(newFile));

4. Использование файлов Guava

Чтобы использовать Guava, нам потребуется загрузить зависимость com.google.guava и включить ее в проект.

<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>31.1-jre</version></dependency>

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

File fileToCopy = new File("c:/temp/testoriginal.txt");File newFile = new File("c:/temp/testcopied.txt");Files.copy(fileToCopy, newFile);

После Java 7 не было никаких серьезных улучшений в пакете Java IO. Поэтому для любого более позднего релиза Java(от Java 8 до Java 14) нам придется отвечать на вышеперечисленные методы.

Исходный код на Github

Прокрутить вверх