使用 java.nio.file.Path 获取目录中的元素

Getting an element inside a directory using java.nio.file.Path's

我目前正在掌握 Java 中的文件管理。据我所知,java.nio.file.Path 是首选的方式。

假设我想将 oldDir 的内容复制到当前为空的 newDir。每次复制文件时,我都需要这一行来获取新文件的路径:

Path newDir = FileSystems.getDefault().getPath("new");
Path oldDir = FileSystems.getDefault().getPath("old");
for (Path oldFile : oldDir) {
    Path newFile = FileSystems.getDefault().getPath("new", oldFile.getFileName().toString()); // Why so complicated? :(
    Files.copy(oldFile, newFile);
}

是否有类似 newDir.getChild(oldFile.getFileName()) 的东西可以做我想做的事,或者真的没有更短的方法吗?

您可以做几件事来简化代码:

  1. 使用 Path#of(String,String...) or Paths#get(String,String...) 创建您的 Path 个实例。两种方法都委托给默认 FileSystem。前者是在 Java 11 中添加的,现在是首选方法。

  2. 使用Path#resolve(Path)将相对路径附加到某个绝对路径。

但是你的代码也有错误。您正在迭代 oldDir,这是有效的,因为 Path 实现了 Iterable<Path>但是,它迭代路径的名称,而不是路径的子项。换句话说,这个:

Path path = Path.of("foo", "bar", "file.txt");
for (Path name : path) {
  System.out.println(name);
}

将输出:

foo
bar
file.txt

如果你想遍历一个目录的子目录,你需要使用类似 Files#list(Path) or Files#newDirectoryStream(Path) 的东西(后者有两个重载)。这两种方法都只 return 目录的直接子目录。还有其他方法可用于递归迭代目录及其子目录;浏览 Files 文档以查看提供的内容。

因此您的代码应该类似于:

Path oldDir = Path.of(...);
Path newDir = Path.of(...);
try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(oldDir)) {
  for (Path oldFile : dirStream) {
    Path newFile = newDir.resolve(oldFile.getFileName());
    Files.copy(oldFile, newFile);
  }
}