Отнесите релятивизм, добавив избыточный каталог «..» - PullRequest
0 голосов
/ 13 февраля 2020

Я копирую файлы из банки в локальную папку.

  • Банка находится в a/b.
  • Папка (в банке) Я попытка извлечь находится в b/c
  • Папка назначения должна быть z, то есть a/b/c/x -> z/x

Когда я использую c.relativize("x"), я получаю ../c/x вместо x.

Это проблема, когда я затем пытаюсь сделать: z.resolve(c.relativize(x)).

Я получаю z/../c/x вместо z/x

Как мне решить эту проблему?

Я пытался z.resolve(c.relativize(x).normalise()), но получил тот же результат

Баночка b в папке a. c - это ресурс (папка) внутри jar b. x - это файл внутри папки c.

Ответы [ 2 ]

0 голосов
/ 13 февраля 2020

Я думаю, что вы неправильно поняли использование path.relativize(Path)

В соответствии с https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Path.html#relativize (java .nio.file.Path) , есть следующее утверждение:

Создает относительный путь между этим путем и заданным путем.

например,

Path pathA = Paths.get("a"); // i.e. /a or /anyDir/anySubDir/a
Path pathB = Paths.get("b"); // i.e. /b or /anyDir/anySubDir/b
pathA.relativize(pathB)

Предположим, что результат равен ../b, что делает это означает?

Это на самом деле говорит вам: поскольку вы находитесь внутри каталога a, если вы хотите получить доступ к каталогу b, вам нужен доступ с помощью этого подхода cd ../b.

relativize(Path) помогает анализировать относительный путь между родительским путем и дочерним путем (то есть, как получить доступ от родительского пути к дочернему пути).

В качестве альтернативы из вашего вопроса похоже, что вы предпочитаете «строить» путь вместо «анализа» относительного пути. relativize(Path) не подходит для этой цели.

Итак, какой из них, «построить» вручную или «проанализировать», вы хотите достичь?

0 голосов
/ 13 февраля 2020
  • Фляга находится в папке A / B /
  • Путь к исходной папке внутри фляги / b / c / с файлом /b/c/xxx.yyy
  • Папка назначения Z
  • Файл назначения должен иметь путь: Z / xxx.yyy

Итак:

    Path sourceZip = Paths.get("/A/B/my.zip");
    URI sourceZipURI = URI.create("jar:" + sourceZip.toUri());

    Path targetFolder = Paths.get("/Z");

    Map<String, Object> senv = new HashMap<>();
    try (FileSystem sourceZipFS = FileSystems.newFileSystem(sourceZipURI, senv, null)) {
        Path folderInZip = sourceZipFS.getPath("/b/c");
        Files.list(folderInZip).forEach(p -> {
            Path target = targetFolder.resolve(folderInZip.relativize(p).toString());
            try {
                Files.createDirectories(target.getParent());
                Files.copy(p, target);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

Основной проблемой было обращение relativize; не в первый раз я столкнулся с недоразумением. child.relativize(parent) дает .., тогда как parent.relativize(child) усекает путь.

Чтобы получить целевой путь, необходимо преобразовать исходный путь в строку, чтобы предотвратить объединение двух разных файловых систем.

(я не позаботился о подкаталогах.)

...