Tengo un programa de Java que se supone debe leer un archivo de una URL (la ubicación de URL es un directorio virtual en un sitio web de IIS; debajo, y en mi prueba inicial, ' m tratarlo como cualquier otra ubicación del sistema de archivos). Lamentablemente, la ruta a todos los archivos que deben leerse incluye un signo de almohadilla (#) en uno de los nombres de directorio, y no hay nada que pueda hacer para cambiar eso. El programa funciona muy bien cuando (como prueba) lo señalo a una ubicación que no tiene ese signo de libra en la ruta.Codificando un signo de libra en un URI de Java
Empecé creando una URL a partir de una cadena que se pasa al programa. Para una ruta de archivo como /Documents/#2012/09/11
(donde los documentos es una parte de windows), que podría conseguir el programa para procesar con éxito si se lo pasé un camino como éste en mi línea de comandos:
file://serverIPaddress/Documents/\%232012/09/07/16/DOC4671179.DOC
Es decir, con el signo de libra codificado manualmente como %23
, y una barra invertida que escapa del% del% 23.
sólo había una cola para conseguir esa URL:
URL url = new URL(filePath); // filePath is passed in
Pero el programa no va a ser alimentados con cuchara un camino codificado de esa manera, así que tuve que encontrar la manera de codificar la libra firmar programáticamente Siguiendo con el buen consejo encontrado en how to encode URL to avoid special characters in java, creé un URI usando un constructor de múltiples argumentos (corté el parámetro que había estado pasando al programa en tres parámetros separados para acomodar ese cambio). Esto es lo que parecía:
URI uri = new URI(protocol, host, filePath, null); // all values are passed in
Eso codificaba correctamente el signo de libra; mi URI fue:
file://serverIPaddress/Documents/%232012/09/07/16/DOC4671179.DOC
Pero sin la barra invertida delante de la %23
, el programa volvió con Connection refused
, presumiblemente porque está interpretando mal el camino sin el beneficio de que la barra invertida.
Así que pensé, bien, agregaré la barra invertida yo mismo. Creé el mismo URI, extraje su rawPath y con un poco de manipulación de cadenas, coloqué una barra invertida delante del% 23. Entonces creé un nuevo URI usando esa nueva cadena:
URI uri = new URI(protocol, host, filePath, null); // all values are passed in
String rawPath = uri.getRawPath();
int pctPos = rawPath.indexOf("%");
String escaped = new String("\\");
String firstPart = rawPath.substring(0,pctPos);
String secondPart = rawPath.substring(pctPos);
String newPath = firstPart + escaped + secondPart;
URI uri2 = new URI(protocol, host, newPath, null);
Sin embargo, como era previsible, que me dio un URI como esta:
file://<serverIPaddress>/Documents/%5C%25232012/09/07/16/DOC4671179.DOC
tanto con la barra invertida y el% codificado. Tiene sentido, pero aún no funciona en el momento de la ejecución.
La API URL dice:
La clase URL por sí mismo no codificar o descodificar cualquier componente URL de acuerdo con el mecanismo de escape se define en la RFC2396.Es la responsabilidad de la persona que llama para codificar cualquier campo, que deben ser escaparon antes de llamar a la URL
Así que pensé, bien, en lugar de crear un segundo URI, voy a crear una URL a partir de ese nueva cadena que genera en el último intento:
URI uri = new URI(protocol, host, filePath, null); // all values are passed in
String rawPath = uri.getRawPath();
int pctPos = rawPath.indexOf("%");
String escaped = new String("\\");
String firstPart = rawPath.substring(0,pctPos);
String secondPart = rawPath.substring(pctPos);
String newPath = firstPart + escaped + secondPart;
URL url = new URL(protocol + "://" + host + newPath);
Pero en ese enfoque, aunque mi nuevo camino parecía bueno:
/Documents/\%232012/09/07/16/DOC4671179.DOC
la URL resultante va recuperando a medida :
file://serverIPAddress/Documents//%232012/09/07/16/DOC4671179.DOC
con una barra inclinada adicional delante del% 23 en lugar de una barra invertida.
Y con eso me he quedado sin ideas.
¿Qué hace que la barra invertida en este último enfoque se convierta en una barra diagonal en la URL?
¿Qué puedo hacer para obtener la URI/URL que necesito?
O tal vez debería preguntar: ¿por qué el programa necesita el% en el% 23 para ser escapado en primer lugar, si ese% 23 es parte de un URI o URL legítimo, y hay algo que puedo hacer sobre eso en su lugar?
¿Qué está pasando la URL que da "conexión rechazada"? – nneonneo
Alguna información en esta pregunta relacionada ServerFault: http://serverfault.com/q/257680 – barrowc
nneonneo - No estoy seguro de entender su pregunta. El programa está abriendo una conexión a la URL, obteniendo un InputStream, luego un InputStreamReader, luego un BufferedReader, y luego leyendo desde el archivo. El error de conexión rechazada se produce al intentar obtener el InputStream. URLConnection urlConn = url.openConnection(); urlConn.setDoInput (verdadero); InputStream is = urlConn.getInputStream(); InputStreamReader isr = new InputStreamReader (es); br = new BufferedReader (isr); – user1664369