当前位置: 首页 > 知识库问答 >
问题:

Java将包含文件和结构的子目录移动到父目录

乐正晟
2023-03-14

试图将文件与结构一起从子目录移动到父目录。并且无法使用files.move()完成此操作。为了说明这个问题,请参阅下面的目录结构。

$ tree
.
└── b
    ├── c
    │   ├── cfile.gtxgt
    │   └── d
    │       ├── dfile.txt
    │       └── e
    └── x
        └── y
            └── z
                ├── 2.txt
                └── p
                    ├── file1.txt
                    └── q
                        ├── file
                        ├── file2.txt
                        └── r
                            └── 123.txt

我想通过Java模拟下面的move命令。

$ mv b/x/y/z/* b/c
b/x/y/z/2.txt -> b/c/2.txt
b/x/y/z/p -> b/c/p

输出应该类似于

$ tree
.
└── b
    ├── c
    │   ├── 2.txt
    │   ├── cfile.gtxgt
    │   ├── d
    │   │   ├── dfile.txt
    │   │   └── e
    │   └── p
    │       ├── file1.txt
    │       └── q
    │           ├── file
    │           ├── file2.txt
    │           └── r
    │               └── 123.txt
    └── x
        └── y
            └── z

在此移动中,目录z下的所有文件和目录都已移动到c

我曾尝试过这样做:

public static void main(String[] args) throws IOException{
    String aPath = "/tmp/test/a/";
    String relativePathTomove = "b/x/y/z/";
    String relativePathToMoveTo = "b/c";

    Files.move(Paths.get(aPath, relativePathTomove), Paths.get(aPath, relativePathToMoveTo), StandardCopyOption.REPLACE_EXISTING);

}

但是,这会导致抛出的java.nio.file.DirectoryNotemptyException:/tmp/test/a/b/c出现异常,如果取出replace_existing选项,则代码抛出java.nio.file.filealReadyExistsException:/tmp/test/a/b/c

这个问题有一个答案,用一个递归函数来解决这个问题。但在我的情况下,它将涉及进一步的复杂性,因为我甚至需要在新的位置重新创建子目录结构。

我没有尝试使用commons-io实用程序方法org.apache.commons.io.fileutils#MoveDirectoryToDirectory的选项,因为这段代码似乎是先复制文件,然后从原始位置删除它们。在我的情况下,文件是巨大的,因此这不是一个首选的选择。

如何在java中实现移动功能而不使用复制。个人文件移动是我唯一的选择吗?

TLDR:如何在java中模拟mv功能,以便将带有文件和结构的子目录移动到父目录。

共有1个答案

方风华
2023-03-14

我最后是这样做的:

创建FileVisitor实现,如下所示:

package com.test.files;

import org.apache.log4j.Logger;

import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Objects;

import static java.nio.file.FileVisitResult.TERMINATE;


public class MoveFileVisitor implements FileVisitor<Path> {

    private static final Logger LOGGER = Logger.getLogger(MoveFileVisitor.class);
    private final Path target;
    private final Path source;

    public MoveFileVisitor(@NotNull Path source, @NotNull Path target) {
        this.target = Objects.requireNonNull(target);
        this.source = Objects.requireNonNull(source);
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        Path relativePath = source.relativize(dir);
        Path finalPath = target.resolve(relativePath);
        Files.createDirectories(finalPath);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Path relativePath = source.relativize(file);
        Path finalLocation = target.resolve(relativePath);
        Files.move(file, finalLocation);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) {
        LOGGER.error("Failed to visit file during move" + file.toAbsolutePath(), exc);
        return TERMINATE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        Files.delete(dir);
        return FileVisitResult.CONTINUE;
    }


}

然后和这位访客走在路上,就像这样:

    String source = "/temp/test/a/b/x/y/z";
    String target = "/temp/test/a/b/c";

    MoveFileVisitor visitor = new MoveFileVisitor(Paths.get(source), Paths.get(target));
    Files.walkFileTree(Paths.get(source), visitor);
 类似资料:
  • Java是否提供了基于文件夹目录的API来完成此任务,或者我们是否需要递归地将每个文件复制到此路径?

  • 问题内容: 我需要将父目录和其他子目录中的文件包含到子目录中。我之前只使用include(’/ rootdirectory / file.php’); 但现在看来似乎行不通。 只是想知道我该怎么做,谢谢。 这是我的确切行: 它给我这个错误(页面仍在运行): 警告: include(/forums/groups.php)[function.include]:无法打开流:C:\ xampp \ htd

  • 我有一个这样结构的小项目: 我在myproject中添加了一个CmakeLists.txt文件,并添加了子目录mylib和myprog。子目录也有一个CMakeList。现在,当我运行cmake时,两个模块都是正确构建的,除非我想在我的程序中使用mylib。我已经找到了全局CmakeList定义的解决方案。但是我更喜欢在mylib中定义这个,以便mylib/包含被添加到项目的包含路径中。我想要一个

  • 我有一个文件夹,其中有一个。dat文件和一个是。zip文件,我必须移动。将文件压缩到另一个目录 我有两个文件夹,一个是 请建议如何实现这一点,我现在所做的是。。。

  • 您好,我想用java创建目录和子目录。我的目录结构是从当前应用程序目录开始的,意思是在当前项目目录中,如下所示。。。 我知道如何创建目录,但我需要创建子目录,我用下面的代码尝试了,下一步应该做什么?

  • 前面小节介绍了如何创建文件和目录、删除文件和目录,本小节介绍如何使用 mv 命令移动文件和目录。 1. 移动文件或目录至另外一个目录下 可以使用 mv file_name 路径 这种格式,移动文件至其他目录下,后面跟的路径可以是相对路径,也可以是绝对路径,这里的路径操作和 cd 命令类似,下面介绍移动文件命令: ls -l # 列出当前目录下所有文件 mv test.txt /usr/local