在Java中如何复制目录

时间:2020-01-09 10:35:30  来源:igfitidea点击:

这篇文章显示了如何在Java中复制目录,其中目录中具有的所有文件和子文件夹都被递归复制到新目录。

在Java中复制目录的方法

要复制包含子目录和所有文件的文件夹树结构,可以在Java-中使用以下方法之一

  • 使用File.listFiles()方法返回代表目录中文件的抽象路径名数组。然后,我们可以迭代数组以列出文件并将其复制到目标目录,我们将必须递归调用方法以在子目录中列出文件。参见示例。
  • 从Java 7开始,我们可以使用Files.walkFileTree方法,该方法遍历以给定起始文件为根的文件树。参见示例。
  • 从Java 8开始,我们可以使用Files.walk()方法,该方法通过遍历以给定起始文件为根的文件树来将Path对象作为流返回。参见示例。

使用的目录结构

此处显示的用于复制Java目录的Java程序使用以下目录结构。

在父文件夹中有一个子文件夹,子文件夹有两个文件,一个文件存储在父文件夹中。

使用Files.walk()方法在Java中复制目录

Java 8及更高版本可以使用Files.walk()方法将Path对象作为流返回。然后可以检查该Stream中的每个路径,以验证它是目录还是文件。如果是文件,则必须将其复制到目标位置,如果是目录,则需要在目标位置创建该目录。

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class CopyDirectory {
  public static void main(String[] args) {
    final String SOURCE_DIR = "F:/theitroad/Parent";
    final String TARGET_DIR = "F:/theitroad/Parent_New";
    directoryCopy(SOURCE_DIR, TARGET_DIR);
  }

  private static void directoryCopy(String sourceDir, String targetDir){
    Path sourcePath = Paths.get(sourceDir);
    Path targetPath = Paths.get(targetDir);
    try(Stream<Path> filePaths = Files.walk(sourcePath)) {
      filePaths.forEach(filePath -> {
        try {
          if (Files.isRegularFile(filePath)) {
            Path newFile = targetPath.resolve(sourcePath.relativize(filePath));
            Files.copy(filePath, newFile);
            System.out.println("Copied file " + newFile);
          }else{
            Path newDir = targetPath.resolve(sourcePath.relativize(filePath));
            Files.createDirectory(newDir);
            System.out.println("Created Directory " + newDir);
          }
        }catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } 
      });
    }catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

输出:

Created Directory F:\theitroad\Parent_New
Created Directory F:\theitroad\Parent_New\Child
Copied file F:\theitroad\Parent_New\Child\hello.txt
Copied file F:\theitroad\Parent_New\Child\Project.docx
Copied file F:\theitroad\Parent_New\Test.txt

使用Files.walkFileTree()方法在Java中复制目录

从Java 7开始,可以使用Files.walkFileTree()方法,使用该方法可以遍历源目录的树结构并复制该过程中的所有文件和子目录。

此方法的参数之一是FileVisitor接口。我们确实需要根据需要提供此接口的实现。

FileVisitor界面有四种方法,要列出文件夹中的文件,我们确实需要实现其中两种。 preVisitDirectory和visitFile。

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class CopyDirectory {
  public static void main(String[] args) {
    final String SOURCE_DIR = "F:/theitroad/Parent";
    final String TARGET_DIR = "G:/Parent_New";
    try {
      directoryCopy(SOURCE_DIR, TARGET_DIR);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  private static void directoryCopy(String sourceDir, String targetDir) throws IOException{
    Path sourcePath = Paths.get(sourceDir);
    Path targetPath = Paths.get(targetDir);
    // Walk the tree structure using WalkFileTree method       
    Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>(){
      @Override
      // Before visiting the directory, create directory 
      public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException {
        Path newDir = targetPath.resolve(sourcePath.relativize(dir));
        System.out.println("Path- " + newDir.toString());
        Files.createDirectory(newDir);
        return FileVisitResult.CONTINUE;
      }
      @Override
      // For each visited file copy it
      public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
        Path newFile = targetPath.resolve(sourcePath.relativize(file));
        System.out.println("Path- " + newFile.getFileName());
        Files.copy(file, newFile);                
        return FileVisitResult.CONTINUE;
      }
    });  
  }
}

使用File.listFiles()方法在Java中复制目录

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

public class CopyDirectory {
  public static void main(String[] args) {
    final String SOURCE_PATH = "F:/theitroad/Parent";
    final String TARGET_PATH = "F:/theitroad/Parent_New";
    File sourceDir = new File(SOURCE_PATH);
    File targetDir = new File(TARGET_PATH);
    try {
      directoryCopy(sourceDir, targetDir);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  private static void directoryCopy(File sourceDir, File targetDir) throws IOException{
    if(sourceDir.isDirectory()){
      // create target directory
      if(!targetDir.exists()){
        targetDir.mkdir();
        System.out.println("Created Directory " + targetDir);
      }
      File[] fileList = sourceDir.listFiles();
      for(File file : fileList){
        File sourceFile =  new File(sourceDir, file.getName());
        File targetFile = new File(targetDir, file.getName());
        // Recursive call in case of directory
        directoryCopy(sourceFile, targetFile);
      }
    }else{ // if it is a file
      Files.copy(sourceDir.toPath(), targetDir.toPath());
      System.out.println("Copied file " + targetDir);
    }
  }
}

输出:

Created Directory F:\theitroad\Parent_New
Created Directory F:\theitroad\Parent_New\Child
Copied file F:\theitroad\Parent_New\Child\hello.txt
Copied file F:\theitroad\Parent_New\Child\Project.docx
Copied file F:\theitroad\Parent_New\Test.txt