2012-09-12 11 views
6

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?

+0

¿Qué está pasando la URL que da "conexión rechazada"? – nneonneo

+0

Alguna información en esta pregunta relacionada ServerFault: http://serverfault.com/q/257680 – barrowc

+0

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

Respuesta

0

no estoy seguro de por qué "\" es necesario. depende del código del servidor. en realidad "\" no es un char legal en las URL, debe codificarse como% 5C

URI la clase es bastante desordenada. Podría cambiar silenciosamente "\" a "/" para las URL de los archivos.

Tal vez puedas probar:

String filePath = "/Documents/#2012/09/11"; 
    filePath = filePath.replace("#", "\\#"); 
    URI uri = new URI("file", "serverAddress", filePath, null); 

El "#" se cambiará a "% 5C% 23". ver si funciona

+0

Gracias por la sugerencia. Como se predijo, 'replace' da el URI' file: // serverAddress/Documents /% 5C% 232012/09/11/filename', pero ese URI también da como resultado un error "IOException: connection refused" cuando se intenta obtener el InputStream (después de crear una URL desde el URI, abrir una conexión a la URL, etc.). – user1664369

+0

¿qué tal 'nueva URL (" file: // "+ serverAddress + filePath.replace (" # "," \\% 23 ")' – irreputable

+0

Buena idea, pero también viene con una URL de 'file: // 172.28.60.68/Documentos //% 232012/09/11/DOC4671179.DOC': una barra diagonal en vez de la barra invertida solicitada. Hay algo en esa clase que no le gusta la barra invertida. Si la clase File acepta una La ruta UNC en su constructor de cadenas tal vez funcione.Me están alejando los problemas de producción, pero lo intentaré cuando tenga un momento. – user1664369

Cuestiones relacionadas