1. Обзор
В этой статье мы рассмотрим распространенные способы копирования файлов на Java.
Во-первых, мы будем использовать стандартные IO и NIO.2 API и две внешние библиотеки: commons-io и guava .
2. 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. НИО.2 API (JDK 7)
С помощью НИО.2 может значительно повысить производительность копирования файлов, так как НИО.2 использует точки входа в систему более низкого уровня.
Давайте подробнее рассмотрим, как работают файлы. copy() метод работает.
Метод copy() дает нам возможность указать необязательный аргумент, представляющий параметр копирования. По умолчанию копирование файлов и каталогов не перезаписывает существующие, а также не копирует атрибуты файлов.
Это поведение можно изменить с помощью следующих параметров копирования:
- REPLACE_EXISTING – заменить файл, если он существует
- COPY_ATTRIBUTES – копирование метаданных в новый файл
- NOFOLLOW_LINKS – не следует переходить по символическим ссылкам
НИО.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)));
}Обратите внимание , что копии каталогов являются неглубокими , что означает, что файлы и подкаталоги в каталоге не копируются.
4. Apache Commons IO
Другим распространенным способом копирования файла с помощью Java является использование библиотеки commons-io .
Во-первых, нам нужно добавить зависимость:
commons-io commons-io 2.8.0
Последнюю версию можно загрузить с сайта Maven Central .
Затем, чтобы скопировать файл, нам просто нужно использовать метод | CopyFile () , определенный в классе FileUtils . Метод принимает исходный и целевой файлы.
Давайте рассмотрим тест 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 , нам нужно включить зависимость:
com.google.guava guava 23.0
Последнюю версию можно найти на Maven Central .
А вот способ копирования файла гуавы:
@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.