У меня есть сервлет, который должен выписать файлы, которые имеют настраиваемое пользователем имя. Я пытаюсь использовать кодирование URI для надлежащего выхода из специальных символов, но JRE, кажется, автоматически преобразовывает закодированные наклонные черты вправо %2F
в разделители пути.
Пример:
File dir = new File("C:\Documents and Setting\username\temp");
String fn = "Top 1/2.pdf";
URI uri = new URI( dir.toURI().toASCIIString() + URLEncoder.encoder( fn, "ASCII" ).toString() );
File out = new File( uri );
System.out.println( dir.toURI().toASCIIString() );
System.out.println( URLEncoder.encode( fn, "ASCII" ).toString() );
System.out.println( uri.toASCIIString() );
System.out.println( output.toURI().toASCIIString() );
Вывод:
file:/C:/Documents%20and%20Settings/username/temp/
Top+1%2F2.pdf
file:/C:/Documents%20and%20Settings/username/temp/Top+1%2F2.pdf
file:/C:/Documents%20and%20Settings/username/temp/Top+1/2.pdf
После того, как новый объект Файла инстанцируют, %2F
последовательность автоматически преобразовывается в наклонную черту вправо, и я заканчиваю с неправильным путем. Кто-либо знает надлежащий способ приблизиться к этой проблеме?
Ядро проблемы, кажется, это
uri.equals( new File(uri).toURI() ) == FALSE
когда существует a %2F
в URI.
Я планирую просто использовать строку URLEncoded дословно вместо того, чтобы пытаться использовать File(uri)
конструктор.
новый файл (URI)
создает файл на основе пути, полученного с помощью URI # getPath ()
вместо-чего вы ожидали- URI # getRawPath ()
. Это похоже на особенность «по замыслу».
У вас есть 2 варианта:
URLEncoder # encode ()
на fn
дважды (примечание: encode ()
, а не кодировщик ()
). новый файл (строка)
. Я думаю, что @BalusC решил прямую проблему в вашем коде. Я просто хотел бы указать на другую проблему
dir.toURI (). ToASCIIString ()
и URLEncoder.encoder (fn, "UTF-8"). ToString ()
Выражения на самом деле делают разные вещи.
Первый кодирует URI как строку, применяя правила кодирования URI в соответствии с грамматикой URI. Так, например, '/' в компоненте пути не будет кодироваться, а '/' в компонентах запроса или фрагмента будет закодирован как% 2F.
Второй кодирует строку fn
, применяя правила кодирования без ссылки на содержимое строки.
Отображение конструктора файла (URI)
из URI файла в файл зависит от системы и недокументировано . Я немного удивлен, что он декодирует % 2F
, но делает то, что делает, и @BalusC объясняет почему. Вывод заключается в том, что потенциально проблематично использовать механизм (URI "файл:"), который явно зависит от системы.
Наконец, неправильно комбинировать такие строки компонентов URI. Это должно быть либо
URI uri = new URI(
dir.toURI().toString() +
URLEncoder.encoder(fn, "UTF-8").toString();
, либо
URI uri = new URI(
dir.toURI().toASCIIString() +
URLEncoder.encoder(fn, "ASCII").toString());