【问题标题】:Java: Move Directory containing files and directories to new pathJava:将包含文件和目录的目录移动到新路径
【发布时间】:2014-04-28 16:58:38
【问题描述】:

我有一个包含一些文件的目录和包含更多文件的子目录。

Folder -  Directory (path -> /home/abc/xyz/Folder)
  ->Abc.txt  (file)
  -> Xyz.zip (file)
  -> Address (Sub Directory)
         -> PWZ.log (file)
         -> CyZ.xml (file)
  -> DataLog.7zip

我要做的是将这个完整的目录从一个路径移动到另一个路径,包括所有文件和子文件夹(及其文件)。

即将此“文件夹”从 /home/abc/xyz/Folder 移动到 /home/abc/subdir/Folder。

Java 是否提供任何 API 来基于 FOLDER 目录执行此任务,或者我们是否需要仅将每个文件递归复制到此路径?

【问题讨论】:

    标签: java file unix


    【解决方案1】:

    您可以使用

    简单地移动目录
    import static java.nio.file.StandardCopyOption.*;
    
    Files.move(new File("C:\\projects\\test").toPath(), new File("C:\\projects\\dirTest").toPath(), StandardCopyOption.REPLACE_EXISTING);
    

    更改源和目​​标路径

    请参考here了解更多详情

    还有来自 API 的注释

     When invoked to move a
         * directory that is not empty then the directory is moved if it does not
         * require moving the entries in the directory.  For example, renaming a
         * directory on the same {@link FileStore} will usually not require moving
         * the entries in the directory. When moving a directory requires that its
         * entries be moved then this method fails (by throwing an {@code
         * IOException}). To move a <i>file tree</i> may involve copying rather
         * than moving directories and this can be done using the {@link
         * #copy copy} method in conjunction with the {@link
         * #walkFileTree Files.walkFileTree} utility method
    

    如果你尝试移动同一个分区中的文件,上面的代码就足够了(它可以移动目录,即使它有条目)。如果不是(而不是移动),您需要使用递归作为提到的其他答案。

    【讨论】:

      【解决方案2】:

      如果您已经导入了Apache Commons

      FileUtils.moveDirectory(oldDir, newDir);
      

      请注意,newDir 不得事先存在。来自 javadocs:

      public static void moveDirectory(File srcDir,
                                       File destDir)
                            throws IOException
      

      移动目录。 当目标目录在另一个文件系统上时,执行“复制和删除”。

      参数:
      srcDir - 要移动的目录
      destDir - 目标目录

      投掷:
      NullPointerException - 如果源或目标为 null
      FileExistsException - 如果目标目录存在
      IOException - 如果源或目标无效
      IOException - 如果移动文件时发生 IO 错误

      【讨论】:

      • 请注意,apache commons 存在软符号链接问题。如果他们被打破,他们将在这里失败。考虑到他们试图尽可能兼容旧的 java,这不太可能改变
      【解决方案3】:

      Files.move() 将在文件系统能够“移动”文件的情况下工作。这通常需要您移动到同一个磁盘上的不同位置。

      【讨论】:

        【解决方案4】:

        最好的方法可能是递归方法,例如: 这是我为将文件移动到临时文件夹而创建的一种方法。

        private boolean move(File sourceFile, File destFile)
        {
            if (sourceFile.isDirectory())
            {
                for (File file : sourceFile.listFiles())
                {
                    move(file, new File(file.getPath().substring("temp".length()+1)));
                }
            }
            else
            {
                try {
                    Files.move(Paths.get(sourceFile.getPath()), Paths.get(destFile.getPath()), StandardCopyOption.REPLACE_EXISTING);
                    return true;
                } catch (IOException e) {
                    return false;
                }
            }
            return false;
        }
        

        【讨论】:

        • 为什么不改用while循环;没有限制。在返回之前可以进行多少次函数调用是有限制的。因为每个函数调用都允许操作系统在进入函数之前存储状态
        【解决方案5】:
           private static void move(File sourceFile, File destFile) {
                if (sourceFile.isDirectory()) {
                    File[] files = sourceFile.listFiles();
                    assert files != null;
                    for (File file : files) move(file, new File(destFile, file.getName()));
                    if (!sourceFile.delete()) throw new RuntimeException();
                } else {
                    if (!destFile.getParentFile().exists())
                        if (!destFile.getParentFile().mkdirs()) throw new RuntimeException();
                    if (!sourceFile.renameTo(destFile)) throw new RuntimeException();
                }
            }
        

        为我工作

        【讨论】:

          【解决方案6】:

          Java 在File.renameTo(File dest) 中使用本机操作系统操作内置了此功能。

          例子:

          new File("/home/alik/Downloads/src").renameTo(new File("/home/alik/Downloads/target"))
          

          【讨论】:

          • 这对我来说失败了(返回 false),但 FileUtils.moveDirectory 有效。
          【解决方案7】:

          在确保目标路径中的目录存在(例如,通过调用 mkdirs())之后,您只需要使用 renameTo 方法(已经存在于 JDK 的 File 类中)。

          【讨论】:

            【解决方案8】:
            public static void move(File srcDir, File destDir) throws IOException {
                FileUtils.copyDirectory(srcDir, destDir, true);
                if(srcDir.isDirectory()) {
                    for(File file: srcDir.listFiles()) {
                        FileUtils.forceDelete(file);
                    }
                }
            }
            

            来自包 org.apache.commons.io 的 FileUtils;

            【讨论】:

            • FileUtils.deleteDirectory(srcDir) 应该递归执行删除工作
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多