Автор оригинала: mkyong.
В Java мы можем использовать Java 1.7 FileVisitor
или Apache Commons IO FileUtils.copydirectory
для копирования каталога, который включает в себя его подкаталоги и файлы.
В этой статье показано несколько распространенных способов копирования каталога на Java.
Файловый посетитель
( Java 7+)Каталог файлов.copydirectory
(Apache commons-io)- Пользовательское копирование с использованием Java 7 NIO и Java 8 Stream.
- Пользовательская копия, устаревший ввод-вывод.
Примечание NIO Files.copy
не поддерживает копирование содержимого каталога, и нам нужно создать индивидуальный метод для копирования содержимого каталога.
1. Просмотрщик файлов (Java 7)
В этом примере показано, как использовать FileVisitor для копирования каталога и его содержимого из /home/mkyong/test/| в
|home/mkyong/test 2/ .
$ tree /home/mkyong/test test ├── test-a1.log ├── test-a2.log └── test-b ├── test-b1.txt ├── test-b2.txt ├── test-c │ ├── test-c1.log │ └── test-c2.log └── test-d ├── test-d1.log └── test-d2.log
1.1 Этот класс расширяет SimpleFileVisitor
для предоставления значений по умолчанию и переопределения только необходимых методов.
package com.mkyong.io.utils; import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.BasicFileAttributes; public class TreeCopyFileVisitor extends SimpleFileVisitor{ private Path source; private final Path target; public TreeCopyFileVisitor(String source, String target) { this.source = Paths.get(source); this.target = Paths.get(target); } @Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { Path resolve = target.resolve(source.relativize(dir)); if (Files.notExists(resolve)) { Files.createDirectories(resolve); System.out.println("Create directories : " + resolve); } return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Path resolve = target.resolve(source.relativize(file)); Files.copy(file, resolve, StandardCopyOption.REPLACE_EXISTING); System.out.println( String.format("Copy File from \t'%s' to \t'%s'", file, resolve) ); return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFileFailed(Path file, IOException exc) { System.err.format("Unable to copy: %s: %s%n", file, exc); return FileVisitResult.CONTINUE; } }
1.2 В этом примере используется Files.walkFileTree
для обхода дерева файлов.
package com.mkyong.io.howto; import com.mkyong.io.utils.TreeCopyFileVisitor; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; public class CopyDirectory1 { public static void main(String[] args) { String fromDirectory = "/home/mkyong/test/"; String toToDirectory = "/home/mkyong/test2/"; try { copyDirectoryFileVisitor(fromDirectory, toToDirectory); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } public static void copyDirectoryFileVisitor(String source, String target) throws IOException { TreeCopyFileVisitor fileVisitor = new TreeCopyFileVisitor(source, target); Files.walkFileTree(Paths.get(source), fileVisitor); } }
Выход
Create directories : /home/mkyong/test2 Copy File from '/home/mkyong/test/test-a2.log' to '/home/mkyong/test2/test-a2.log' Copy File from '/home/mkyong/test/test-a1.log' to '/home/mkyong/test2/test-a1.log' Create directories : /home/mkyong/test2/test-b Copy File from '/home/mkyong/test/test-b/test-b1.txt' to '/home/mkyong/test2/test-b/test-b1.txt' Create directories : /home/mkyong/test2/test-b/test-c Copy File from '/home/mkyong/test/test-b/test-c/test-c2.log' to '/home/mkyong/test2/test-b/test-c/test-c2.log' Copy File from '/home/mkyong/test/test-b/test-c/test-c1.log' to '/home/mkyong/test2/test-b/test-c/test-c1.log' Copy File from '/home/mkyong/test/test-b/test-b2.txt' to '/home/mkyong/test2/test-b/test-b2.txt' Create directories : /home/mkyong/test2/test-b/test-d Copy File from '/home/mkyong/test/test-b/test-d/test-d2.log' to '/home/mkyong/test2/test-b/test-d/test-d2.log' Copy File from '/home/mkyong/test/test-b/test-d/test-d1.log' to '/home/mkyong/test2/test-b/test-d/test-d1.log' Done
Проверьте новый каталог.
$ tree /home/mkyong/test2 test2 ├── test-a1.log ├── test-a2.log └── test-b ├── test-b1.txt ├── test-b2.txt ├── test-c │ ├── test-c1.log │ └── test-c2.log └── test-d ├── test-d1.log └── test-d2.log
Примечание Официальный Пример копирования Java копирует все, включая атрибут файла. Однако это сложнее для чтения; этот пример упрощает метод только для копирования файлов и каталогов и исключает атрибуты.
2. Каталог файлов.copydirectory (Apache commons-io)
В этом примере используется FileUtils.copydirectory
для копирования каталога и его содержимого используется удобный и простой API.
commons-io commons-io 2.7
import org.apache.commons.io.FileUtils; //... public static void copyFileCommonIO(String from, String to) throws IOException { File fromDir = new File(from); File toDir = new File(to); FileUtils.copyDirectory(fromDir, toDir); }
3. Java NIO и поток.
В этом примере используются файлы Java 8 .список
для имитации перемещения файлов и Java 7 NIO Файлы
для проверки, создания и копирования каталога и его содержимого.
package com.mkyong.io.howto; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.util.stream.Stream; public class CopyDirectory3 { public static void main(String[] args) { String fromDirectory = "/home/mkyong/test/"; String toToDirectory = "/home/mkyong/test2/"; try { copyDirectoryJavaNIO(Paths.get(fromDirectory), Paths.get(toToDirectory)); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } public static void copyDirectoryJavaNIO(Path source, Path target) throws IOException { // is this a directory? if (Files.isDirectory(source)) { //if target directory exist? if (Files.notExists(target)) { // create it Files.createDirectories(target); System.out.println("Directory created : " + target); } // list all files or folders from the source, Java 1.8, returns a stream // doc said need try-with-resources, auto-close stream try (Streampaths = Files.list(source)) { // recursive loop paths.forEach(p -> copyDirectoryJavaNIOWrapper( p, target.resolve(source.relativize(p))) ); } } else { // if file exists, replace it Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING); System.out.println( String.format("Copy File from \t'%s' to \t'%s'", source, target) ); } } // extract method to handle exception in lambda public static void copyDirectoryJavaNIOWrapper(Path source, Path target) { try { copyDirectoryJavaNIO(source, target); } catch (IOException e) { System.err.println("IO errors : " + e.getMessage()); } } }
4. Унаследованный IO
Этот пример аналогичен методу 3. Вместо этого он придерживается устаревшего ввода-вывода java.io . *
, просто для справки.
package com.mkyong.io.howto; import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.util.stream.Stream; public class CopyDirectory4 { public static void main(String[] args) { String fromDirectory = "/home/mkyong/test/"; String toToDirectory = "/home/mkyong/test2/"; try { copyDirectoryLegacyIO( new File(fromDirectory), new File(toToDirectory)); } catch (IOException e) { e.printStackTrace(); } System.out.println("Done"); } public static void copyDirectoryLegacyIO(File source, File target) throws IOException { if (source.isDirectory()) { //if directory not exists, create it if (!target.exists()) { if (target.mkdir()) { System.out.println("Directory copied from " + source + " to " + target); } else { System.err.println("Unable to create directory : " + target); } } // list all the directory contents, file walker String[] files = source.list(); if (files == null) { return; } for (String file : files) { //construct the src and dest file structure File srcFile = new File(source, file); File destFile = new File(target, file); //recursive copy copyDirectoryLegacyIO(srcFile, destFile); } } else { //if file, then copy it //Use bytes stream to support all file types InputStream in = null; OutputStream out = null; try { in = new FileInputStream(source); out = new FileOutputStream(target); byte[] buffer = new byte[1024]; int length; //copy the file content in bytes while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } System.out.println("File copied from " + source + " to " + target); } catch (IOException e) { System.err.println("IO errors : " + e.getMessage()); } finally { if (in != null) { in.close(); } if (out != null) { out.close(); } } } } }
Примечание Java, после 20+лет , до сих пор нет официального API для копирования каталога, как сложно создать Каталог файлов.копировать()
?
Скачать Исходный Код
$клон git $клон git
$cd java-ввод-вывод
Рекомендации
- Пример копирования Java
- Файлы JavaDoc
- Входной поток JavaDoc
- Выходной поток JavaDoc
- Файловый редактор javadoc
- Общий доступ Apache IO
- Как скопировать файл на Java
- Java – Как вывести список всех файлов в каталоге?
Оригинал: “https://mkyong.com/java/how-to-copy-directory-in-java/”