Ответ 1
Текущая рекомендация (с JDK 1.7+) заключается в преобразовании URL → URI → Путь. Итак, чтобы преобразовать URL-адрес в файл, вы должны сказать Paths.get(url.toURI()).toFile()
. Если вы не можете использовать JDK 1.7, я бы рекомендовал new File(URI.getSchemeSpecificPart())
.
Преобразование файла → URI: сначала я покажу вам несколько примеров того, какие URI вы, вероятно, получите в Java.
-classpath URLClassLoader File.toURI() Path.toUri()
C:\Program Files file:/C:/Program%20Files/ file:/C:/Program%20Files/ file:///C:/Program%20Files/
C:\main.c++ file:/C:/main.c++ file:/C:/main.c++ file:///C:/main.c++
\\VBOXSVR\Downloads file://VBOXSVR/Downloads/ file:////VBOXSVR/Downloads/ file://VBOXSVR/Downloads/
C:\Résume.txt file:/C:/R%c3%a9sume.txt file:/C:/Résume.txt file:///C:/Résume.txt
\\?\C:\Windows (non-path) file://%3f/C:/Windows/ file:////%3F/C:/Windows/ InvalidPathException
Некоторые наблюдения об этих URI:
- Спецификации URI RFC 1738: URL, замененные RFC 2396: URI, замененные RFC 3986: URI. (WHATWG также имеет спецификацию URI, но в ней не указывается, как интерпретировать URI файлы.) Любые зарезервированные символы в пути указаны в процентах, Символы ascii в URI передаются в процентах при вызове URI.toASCIIString().
- File.toURI() хуже, чем Path.toUri(), потому что File.toURI() возвращает необычный не-RFC 1738 URI (дает файл:/вместо файла:///) и не форматирует URI для UNC-путей в соответствии с предпочтительным форматом Microsoft. Ни один из этих URI UNC не работает в Firefox, хотя (для Firefox требуется файл://///).
- Путь более строгий, чем файл; вы не можете создать недопустимый путь из "\.\" префикса. "Эти префиксы не используются как часть самого пути", но они могут быть переданы в API Win32.
Преобразование URI → файла: Давайте попробуем преобразовать предыдущие примеры в файлы:
new File(URI) Paths.get(URI) new File(URI.getSchemeSpecificPart())
file:///C:/Program%20Files C:\Program Files C:\Program Files C:\Program Files
file:/C:/Program%20Files C:\Program Files C:\Program Files C:\Program Files
file:///C:/main.c++ C:\main.c++ C:\main.c++ C:\main.c++
file://VBOXSVR/Downloads/ IllegalArgumentException \\VBOXSVR\Downloads\ \\VBOXSVR\Downloads
file:////VBOXSVR/Downloads/ \\VBOXSVR\Downloads \\VBOXSVR\Downloads\ \\VBOXSVR\Downloads
file://///VBOXSVR/Downloads \\VBOXSVR\Downloads \\VBOXSVR\Downloads\ \\VBOXSVR\Downloads
file://%3f/C:/Windows/ IllegalArgumentException IllegalArgumentException \\?\C:\Windows
file:////%3F/C:/Windows/ \\?\C:\Windows InvalidPathException \\?\C:\Windows
Опять же, использование Paths.get(URI)
предпочтительнее new File(URI)
, потому что Path может обрабатывать URI UNC и отклонять недопустимые пути с префиксом \? \. Но если вы не используете Java 1.7, скажите new File(URI.getSchemeSpecificPart())
.
Кстати, не используйте URLDecoder
, чтобы декодировать URL-адрес файла. Для файлов, содержащих "+", например "файл:///C:/main.c++", URLDecoder
превратит его в "C:\main.c "! URLDecoder
предназначен только для синтаксического анализа представлений HTML-формы приложения /x -www-form-urlencoded в запросе URI (param=value¶m=value
), а не для недопущения пути URI.
2014-09: отредактирован для добавления примеров.