【问题标题】:How to recursively copy entire directory including parent folder in Java如何递归复制整个目录,包括Java中的父文件夹
【发布时间】:2012-07-25 14:20:17
【问题描述】:

我目前正在处理从一个地方到另一个地方的文件夹。它工作正常,但它没有复制所有其余文件和文件夹所在的原始文件夹。这是我正在使用的代码:

public static void copyFolder(File src, File dest) throws IOException {
  if (src.isDirectory()) {
    //if directory not exists, create it
    if (!dest.exists()) {
      dest.mkdir();
    }
    //list all the directory contents
    String files[] = src.list();
    for (String file : files) {
      //construct the src and dest file structure
      File srcFile = new File(src, file);
      File destFile = new File(dest+"\\"+src.getName(), file);
      //recursive copy
      copyFolder(srcFile,destFile);
    }
  } else {
    //if file, then copy it
    //Use bytes stream to support all file types
    InputStream in = new FileInputStream(src);
    OutputStream out = new FileOutputStream(dest); 
    byte[] buffer = new byte[1024];
    int length;
    //copy the file content in bytes 
    while ((length = in.read(buffer)) > 0){
      out.write(buffer, 0, length);
    }
    in.close();
    out.close();
    System.out.println("File copied from " + src + " to " + dest);
  }
}

所以我有文件夹 src C:\test\mytest\..all folders..

我想复制到C:\test\myfiles

但我没有得到C:\test\myfiles\mytest\..all folders..,而是得到C:\test\myfiles\..all folders..

【问题讨论】:

    标签: java directory


    【解决方案1】:

    【讨论】:

    【解决方案2】:

    有一个tutorial for copying files using java.nio 带有一个递归副本example code on Oracle Docs。它适用于 java se 7+。它使用 might cause some issues on ntfs with junction points 的 Files.walkFileTree 方法。为避免使用 Files.walkFileTree,可能的解决方案如下所示:

    public static void copyFileOrFolder(File source, File dest, CopyOption...  options) throws IOException {
        if (source.isDirectory())
            copyFolder(source, dest, options);
        else {
            ensureParentFolder(dest);
            copyFile(source, dest, options);
        }
    }
    
    private static void copyFolder(File source, File dest, CopyOption... options) throws IOException {
        if (!dest.exists())
            dest.mkdirs();
        File[] contents = source.listFiles();
        if (contents != null) {
            for (File f : contents) {
                File newFile = new File(dest.getAbsolutePath() + File.separator + f.getName());
                if (f.isDirectory())
                    copyFolder(f, newFile, options);
                else
                    copyFile(f, newFile, options);
            }
        }
    }
    
    private static void copyFile(File source, File dest, CopyOption... options) throws IOException {
        Files.copy(source.toPath(), dest.toPath(), options);
    }
    
    private static void ensureParentFolder(File file) {
        File parent = file.getParentFile();
        if (parent != null && !parent.exists())
            parent.mkdirs();
    } 
    

    【讨论】:

    • 谢谢。我已经扩展了答案。
    • 你拯救了我的一天! :)
    【解决方案3】:

    你也可以试试Apache FileUtils复制目录

    【讨论】:

      【解决方案4】:

      你应该试试apache commons FileUtils

      【讨论】:

        【解决方案5】:

        使用 java.nio:

        import java.io.IOException;
        import java.nio.file.*;
        import java.nio.file.attribute.BasicFileAttributes;
        
        public static void copy(String sourceDir, String targetDir) throws IOException {
        
            abstract class MyFileVisitor implements FileVisitor<Path> {
                boolean isFirst = true;
                Path ptr;
            }
        
            MyFileVisitor copyVisitor = new MyFileVisitor() {
        
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    // Move ptr forward
                    if (!isFirst) {
                        // .. but not for the first time since ptr is already in there
                        Path target = ptr.resolve(dir.getName(dir.getNameCount() - 1));
                        ptr = target;
                    }
                    Files.copy(dir, ptr, StandardCopyOption.COPY_ATTRIBUTES);
                    isFirst = false;
                    return FileVisitResult.CONTINUE;
                }
        
                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    Path target = ptr.resolve(file.getFileName());
                    Files.copy(file, target, StandardCopyOption.COPY_ATTRIBUTES);
                    return FileVisitResult.CONTINUE;
                }
        
                @Override
                public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
                    throw exc;
                }
        
                @Override
                public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                    Path target = ptr.getParent();
                    // Move ptr backwards
                    ptr = target;
                    return FileVisitResult.CONTINUE;
                }
            };
        
            copyVisitor.ptr = Paths.get(targetDir);
            Files.walkFileTree(Paths.get(sourceDir), copyVisitor);
        }
        

        【讨论】:

        • 尝试用一些介绍来解释你的答案适用的地方
        【解决方案6】:

        【讨论】:

          【解决方案7】:

          此解决方案非常简单,但不是独立于平台的,因为命令是以纯文本形式提供给操作系统的。 (此示例适用于基于 Unix 的 shell,对于 Windows,命令看起来会有些不同 cp 称为 copy)。

          String source = "/user/.../testDir";
          String destination = "/Library/.../testDestination/testDir";
          String command = "cp -r " + source + " " + destination;
          Process p;
          try {
              p = Runtime.getRuntime().exec(command);
              p.waitFor();
          } catch (InterruptedException | IOException e) {
              // Error handling
          }
          

          如果要将对象复制到同名的子文件夹中,请将其添加到目标路径中,否则省略,则文件夹内容将直接复制到目标路径中。

          编辑:不幸的是,这个解决方案不适用于网络驱动器。原因我不知道(但我承认我没有任何理由去挖掘)

          【讨论】:

            【解决方案8】:

            主要问题是这样的:

              dest.mkdir();
            

            只创建一个目录,不创建父目录,第一步后需要创建两个目录,所以将mkdir替换为mkdirs。 在那之后,我猜你会有重复的子目录,因为你的递归(像 C:\test\myfiles\mytest\dir1\dir1\subdir1\subdir1...),所以也尝试修复这些行:

                File destFile = new File(dest, src.getName());
                /**/
                OutputStream out = new FileOutputStream(new File(dest, src.getName())); 
            

            【讨论】:

              【解决方案9】:

              此代码将文件夹从源复制到目标:

                  public static void copyDirectory(String srcDir, String dstDir)
                  {
              
                      try {
                          File src = new File(srcDir);
                          String ds=new File(dstDir,src.getName()).toString();
                          File dst = new File(ds);
              
                          if (src.isDirectory()) {
                              if (!dst.exists()) {
                                  dst.mkdir();
                              }
              
                              String files[] = src.list();
                              int filesLength = files.length;
                              for (int i = 0; i < filesLength; i++) {
                                  String src1 = (new File(src, files[i]).toString());
                                  String dst1 = dst.toString();
                                  copyDirectory(src1, dst1);
              
                              }
                          } else {
                              fileWriter(src, dst);
                          }
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  }
              public static void fileWriter(File srcDir, File dstDir) throws IOException
              {
                      try {
                          if (!srcDir.exists()) {
                              System.out.println(srcDir + " doesnot exist");
                              throw new IOException(srcDir + " doesnot exist");
                          } else {
                              InputStream in = new FileInputStream(srcDir);
                              OutputStream out = new FileOutputStream(dstDir);
                              // Transfer bytes from in to out
                              byte[] buf = new byte[1024];
                              int len;
                              while ((len = in.read(buf)) > 0) {
                                  out.write(buf, 0, len);
                              }
                              in.close();
                              out.close();
              
                          }
                      } catch (Exception e) {
              
                      }
                  }
              

              【讨论】:

              • 撤销第二个帖子:) 已经为异常提供了一些自定义类,我修改了第一个帖子本身..它工作正常!..
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-04-23
              • 1970-01-01
              • 1970-01-01
              • 2016-10-25
              • 2015-03-01
              • 1970-01-01
              相关资源
              最近更新 更多