Могу ли я создать Linux-путь в Java, работающий в Windows без жесткого программирования? - PullRequest
0 голосов
/ 12 июня 2018

Я использую контейнеры Docker для размещения хаба Selenium и некоторых узлов, и мне нужно помочь этим тестам найти статический HTML-файл.Я сопоставил папку на локальном диске с узлами Docker.

Мой код (Java 10, работающий в Windows 10) выглядит следующим образом:

private URL getTestPageUrl() {
    var folder = Common.getString(Prop.testAssetFolder);
    var pathToTestPage = Paths.get(folder, "selectorTestPage.html");
    URL url = null;
    try { url = pathToTestPage.toUri().toURL(); }
    catch (MalformedURLException e) { /* Most pointlessly checked exception ever. */ }
    return url;
}

pathToTestPage выходиткак \testAssets\selectorTestPage.html, который .toUri().toURL() затем преобразуется в file:/C:/testAssets/selectorTestPage.html, что, конечно, не работает в Linux.

Очевидно, я могу просто склеить некоторые имена папок и файлов и некоторые жестко запрограммированные / чтобы получить этот путь в формате Linux, но есть ли более элегантный способ?

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Примечание перед прочтением : Javadoc FileSystem и связанный API описывают поведение многих методов как зависящее от реализации.Это имеет смысл, поскольку разные файловые системы имеют разные правила.При этом значения по умолчанию FileSystem достаточно хорошо определены (поскольку они моделируют основные операционные системы).

Статический метод Paths.get(String, String...) делегирует значение по умолчанию FileSystem платформы.Это то же самое FileSystem, которое вы получите от FileSystems.getDefault().Это означает, что в Windows он делегирует WindowsFileSystem, в Linux он делегирует LinuxFileSystem (если это имя) и так далее.Ответственность за создание Path объекта FileSystem лежит на самом деле.Это включает в себя такие вещи, как добавление правильных разделителей и проверка каждого имени.Разделитель публично определяется как FileSystem.getSeparator().

Когда вы вызываете Paths.get("foo", "bar", "file.txt") в Windows, возвращаемый Path получается равным foo\bar\file.txt.В Linux это станет foo/bar/file.txt.Я даже считаю, что, по крайней мере, в Windows прощает ввод имени, которое на самом деле является путем с неправильными разделителями.Например, вызов Paths.get("foo/bar/file.txt") в Windows по-прежнему возвращает foo\bar\file.txt.

У вас также есть вызовы path.toUri().toURL().Javadoc для toUri() состояний (выделено мной):

Этот метод создает абсолютный URI со схемой, равной схеме URI, которая идентифицирует поставщика.Точная форма конкретной части схемы сильно зависит от поставщика.

В случае поставщика по умолчанию URI является иерархическим с компонентом пути, равным absolute .

...

Броски

...

SecurityException - В случае поставщика по умолчанию и установлен менеджер безопасности, toAbsolutePath метод выдает исключение безопасности.

Вызов Path.toUri() для относительного Path сначала найдет абсолютное значение Path.И, основываясь на Javadoc, я бы сказал, что по умолчанию FileSystem s получит абсолютное Path при вызове Path.toAbsolutePath().Это означает, что Path преобразуется в абсолютный путь в зависимости от платформы, на которой вы сейчас находитесь.Как видите, вызов в Windows привел к добавлению C:/ в качестве root.Это не произойдет, скажем, на машине Linux.Кроме того, теперь URI определяет разделители, используемые в пути.И вызов toURL() также определяется как URI.


Все это говорит о том, что при использовании java.nio, очевидно, могут возникнуть проблемы между платформами.Всегда будут ошибки и несовместимости, за которыми вы должны следить.Примером может служить то, что в Windows есть регистр нечувствительных файловых систем, в то время как в Linux (я считаю) регистр чувствителен .

Единственный верный способ узнать ваш кодПравильно кроссплатформенный режим для запуска тестов на каждой целевой платформе.

0 голосов
/ 12 июня 2018

Вы должны быть в состоянии использовать FileSystemProvider в NIO.2, в частности sun.nio.fs.UnixFileSystemProvider .

Это позволяет вам делать что-то вроде

FileSystemProvider fsp = new UnixFileSystemProvider();
Path path = fsp.getPath(pathToTestPage.toUri());
...