Java: File.toURI().toURL() в файле Windows

Я работаю в системе Windows XP с JRE 1.6.

Я делаю это :

public static void main(String[] args) {
    try {
        System.out.println(new File("C:\\test a.xml").toURI().toURL());
    } catch (Exception e) {
        e.printStackTrace();
    }       
}

и я получаю это: file:/C:/test%20a.xml

Почему в данном URL-адресе нет двух косых черт перед C:? Я ожидал file://C:.... Это нормальное поведение?


ИЗМЕНИТЬ:

Из исходного кода Java: java.net.URLStreamHandler.toExternalForm(URL)

    result.append(":");
    if (u.getAuthority() != null && u.getAuthority().length() > 0) {
        result.append("//");
        result.append(u.getAuthority());
    }

Кажется, что часть авторитета URL-адреса файла имеет значение null или пуста, и поэтому двойная косая черта пропускается. Так что же такое авторитетная часть URL-адреса и действительно ли она отсутствует в файловом протоколе?


person glmxndr    schedule 15.07.2009    source источник
comment
Я очень надеюсь, что вы поставили пробелы перед {s...   -  person Zifre    schedule 15.07.2009
comment
На какой версии Windows вы работаете? На самом деле не имеет значения, можете ли вы проанализировать его с помощью нового URL (строка).   -  person akarnokd    schedule 15.07.2009
comment
@ kd304: ну, это имеет значение, если я анализирую результат с помощью чего-то другого, кроме URL (String), что я и делаю.   -  person glmxndr    schedule 15.07.2009
comment
Забавно, что javadoc для java.net.URL по-прежнему ссылается на исходные страницы справки NCSA Mosaic, которые, что неудивительно, являются неработающими ссылками. Я думаю, что я мог бы зарегистрировать ошибку против этого....   -  person skaffman    schedule 15.07.2009
comment
@subtenante: Зачем тебе самому это анализировать?   -  person akarnokd    schedule 15.07.2009
comment
@ kd304: не я, а какая-то другая библиотека.   -  person glmxndr    schedule 15.07.2009
comment
Я думаю, что file://C:... — это «расслабление» Windows: правильно должно быть file:///C:.... См. superuser.com/questions/352133.   -  person Stuart Rossiter    schedule 07.11.2014


Ответы (3)


Это интересный вопрос.

Перво-наперво: я получаю те же результаты на JRE6. Я даже понимаю это, когда отрезаю часть toURL().

RFC2396 на самом деле не требует двух косых черт. Согласно разделу 3:

Синтаксис URI зависит от схемы. В общем случае абсолютный URI записывается следующим образом:

<scheme>:<scheme-specific-part>

При этом RFC2396 был заменен RFC3986, в котором говорится

Общий синтаксис URI состоит из иерархической последовательности компонентов, называемых схемой, полномочным органом, путем, запросом и фрагментом.

  URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

  hier-part   = "//" authority path-abempty
              / path-absolute
              / path-rootless
              / path-empty

Компоненты схемы и пути обязательны, хотя путь может быть пустым (без символов). При наличии полномочий путь должен быть либо пустым, либо начинаться с символа косой черты ("/"). Если полномочия отсутствуют, путь не может начинаться с двух символов косой черты ("//"). Эти ограничения приводят к пяти различным правилам ABNF для пути (раздел 3.3), только одно из которых будет соответствовать любой заданной ссылке URI.

Итак, вот и все. Поскольку URI файлов не имеют сегмента полномочий, им запрещено начинать с //.

Однако этот RFC появился только в 2005 году, а Java ссылается на RFC2396, поэтому я не знаю, почему он следует этому соглашению, поскольку URL-адреса файлов до нового RFC всегда имели две косые черты.

person Powerlord    schedule 15.07.2009
comment
Да, но: tools.ietf.org/html/rfc1738 . Раздел 3.10 говорит мне, что файлы должны иметь двойную косую черту в URL-адресах. - person glmxndr; 15.07.2009
comment
И пример в конце раздела 1.1 RFC3986 имеет следующий пример: file:///etc/hosts. - person glmxndr; 15.07.2009
comment
Я тоже это заметил. Иногда я думаю, что они должны просто упростить чтение спецификаций. - person Powerlord; 15.07.2009
comment
Раздел 3.2.2 RFC 3986 разъясняет это, отмечая, что authority может быть пустым: Если схема URI определяет значение по умолчанию для хоста, то это значение по умолчанию применяется, когда субкомпонент хоста не определен или когда зарегистрированное имя пусто (нулевая длина). Например, схема URI файла определена таким образом, что отсутствие полномочий, пустой хост и локальный хост означают компьютер конечного пользователя, тогда как схема http считает отсутствие полномочий или пустой хост недействительными. - person Ilmari Karonen; 08.01.2013
comment
Да, URL-адрес RFC1738, кажется, противоречит этому, как говорит GhiOm: см. также superuser.com/questions/352133. Обратите внимание, что некоторые библиотеки ожидают версию с тройной косой чертой, например привязки Subversion Java JavaHL API, поэтому вам придется вручную выполнить "file://" + myFile.toURI().getRawPath() - person Stuart Rossiter; 07.11.2014

Чтобы ответить, почему вы можете иметь оба:

file:/path/file
file:///path/file
file://localhost/path/file

RFC3986 (3.2.2. Хост) гласит:

«Если схема URI определяет значение по умолчанию для узла, то это значение по умолчанию применяется, когда подкомпонент узла не определен или когда зарегистрированное имя пусто (нулевая длина). Например, схема URI «файл» определена таким образом, что пустой хост и "localhost" означают машину конечного пользователя, тогда как схема "http" считает отсутствующие полномочия или пустой хост недействительными".

Таким образом, схема «файл» преобразует file:///path/file в контекст машины конечного пользователя, даже если полномочия являются пустым хостом.

person rbeede    schedule 21.01.2012

Что касается использования его в браузере, это не имеет значения. Обычно я видел file:///..., но один, два или три '/' будут работать. Это заставляет меня думать (не глядя на документацию по java), что это нормальное поведение.

person Jeremy Cron    schedule 15.07.2009
comment
Я понимаю 3 слэша : // + /C: что логично. Проблема в том, что я не использую браузер. - person glmxndr; 15.07.2009
comment
3 Косая черта имеет смысл в системе типа UNIX; третья косая черта — это корневой каталог. file:///etc/passwd — это файл /etc/passwd. - person Powerlord; 15.07.2009