Ошибка java.nio.file.Path с путями VSS (теневое копирование тома)

Используя VSS, я создал моментальный снимок тома и могу успешно обращаться к файлам на нем:

C:\> type \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Users\Eric\Desktop\test.txt
test text 1/2
test text 2/2

Когда я пытаюсь получить доступ к тому же файлу из java с помощью java.io.File, он работает нормально. Однако я не могу преобразовать его в java.nio.file.Path, вызвав toPath следующим образом:

File file = newFile(vssPath)
Path path = file.toPath()

Это приведет к трассировке исключения. Это известная проблема для OpenJDK, и я получаю тот же результат с java 1.8. .91:

STACKTRACE:: java.nio.file.InvalidPathException: Illegal character [?] in path at index 2: \\?    \GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Users\qa\Desktop\lock_full.txt
    at sun.nio.fs.WindowsPathParser.nextSlash(Unknown Source)
    at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
    at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
    at sun.nio.fs.WindowsPath.parse(Unknown Source)
    at sun.nio.fs.WindowsFileSystem.getPath(Unknown Source)
    at java.io.File.toPath(Unknown Source)

Поскольку я не могу получить Path, есть определенные API, которые я не могу использовать, например java.nio.channels.AsynchronousFileChannel, которые можно создать только с Path.

Есть ли какой-либо альтернативный синтаксис для доступа к файлу теневой копии, который не противоречит этому ограничению JDK? В упомянутом выше билете OpenJDK рекомендуется просто опустить префикс long-UNC (\\?), но я не нашел никаких вариантов этого, которые кажутся законными. Например, все следующие действия терпят неудачу:

    C:\> type \\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Users\Eric\Desktop\test.txt
    C:\> type \\Device\HarddiskVolumeShadowCopy1\Users\Eric\Desktop\test.txt
    C:\> type \\HarddiskVolumeShadowCopy1\Users\Eric\Desktop\test.txt

Если нет альтернативного пути, который я мог бы использовать для вызова toPath(), то есть ли другой способ получить java.nio.file.Path, который не противоречит ограничениям парсера?


person Eric    schedule 01.12.2016    source источник
comment
Я думаю, что Алан говорит, что удаление префикса может сработать в Java. Из командной строки это точно не сработает. (Идея заключается в том, что Java автоматически вернет префикс обратно при вызове Windows API. Хотя я не совсем понимаю, как он может определить, когда это правильно.)   -  person Harry Johnston    schedule 02.12.2016
comment
Возможно, java правильно добавит префикс, когда потребуется, потому что длина пути больше MAX_PATH? Это имело бы смысл, но, конечно, не помогает при работе с VSS.   -  person Eric    schedule 02.12.2016
comment
Я подумал об этом, но OP в связанном билете сказал, что это решило их проблему, и они не похоже имеют дело с длинными путями. Хотя трудно быть уверенным.   -  person Harry Johnston    schedule 02.12.2016


Ответы (1)


В отсутствие своевременного решения моя команда обсудила:

  1. создать нашу собственную реализацию java.nio.file.Path (или найти ее в какой-нибудь другой библиотеке)
  2. изменить код, чтобы избежать использования java.nio.file.Path

... и мы остановились на №2. # 1 был бы более общим обходным путем, вероятно, должен быть принятый ответ, если кто-то когда-нибудь сделает это и поделится.

person Eric    schedule 02.12.2016