Получение элемента внутри каталога с использованием java .nio.file.Path's - PullRequest
0 голосов
/ 16 июня 2020

В настоящее время я занимаюсь управлением файлами в Java. Насколько я читал, предпочтительным способом является java .nio.file.Path.

Скажем, я хочу скопировать содержимое oldDir в, в настоящее время пустой, newDir. Каждый раз, когда я копирую файл, мне нужна эта строка loong, чтобы получить путь к newFile:

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 Ответ

2 голосов
/ 16 июня 2020

Есть несколько вещей, которые вы можете сделать, чтобы упростить код:

  1. Используйте Path#of(String,String...) или 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) или Files#newDirectoryStream(Path) (у последнего две перегрузки). Оба эти метода возвращают только непосредственных дочерних элементов каталога. Существуют и другие методы рекурсивного перебора каталога и его подкаталогов; просмотрите документацию 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);
  }
}
...