2012-07-13 18 views
5

Acabo de encontrar un comportamiento peculiar con getResourceAsInputStream que esperaba que alguien pudiera arrojar algo de luz.¿Por qué getResourceAsStream con una cadena vacía devuelve un InputStream vacío?

Pasando este método, el nombre de un recurso inexistente devuelve nulo, como era de esperar. Sin embargo, pasarle una cadena vacía o llena de espacio en realidad devuelve un InputStream válido con cero bytes en él. Solo cadenas vacías o llenas de espacio parecen hacer esto; espacios en blanco como "\ t" o "\ n" darán como resultado un nulo.

¿Tiene este comportamiento previsto? Si es así, ¿cuál es su propósito?

this.class.getResourceAsStream("no_such_resource"); // returns null 
this.class.getResourceAsStream("");     // returns an InputStream 
this.class.getResourceAsStream(" ");    // returns an InputStream 
this.class.getResourceAsStream("\t");    // returns null 

Respuesta

3

getResourceAsStream le pide al ClassLoader que construya una URL para la ruta. La ruta con una cadena vacía o espacios en blanco en el extremo apunta al directorio de archivos donde reside su archivo .class de clases, por lo que construye un objeto FileURLConnection. getResourceAsStream a su vez pregunta ese objeto a getInpuStream() y la implementación crea una lista de directorios ordenados en una cadena, la convierte en bytes de acuerdo con la configuración regional predeterminada y le da un ByteArrayInputStream en estos bytes.

comportamiento

FileURLConnections no está muy bien documentada, pero si la búsqueda ...

+1

¡Gran explicación! Vale la pena señalar que esta es una peculiaridad de 'FileURLConnection' que no es compartida por' JarURLConnection'; ejecutar exactamente el mismo código, pero con las clases empaquetadas en un contenedor, no generará una lista (de acuerdo con mis pruebas, al menos). –

+0

Aha, ¡eso tiene sentido! Gracias por la explicación. –

4

probar este código:

InputStream is = this.class.getResourceAsStream(""); 
BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
String line; 
while((line = br.readLine()) != null) System.out.println(line); 
br.close(); 

esto imprimirá una lista de clases que se encuentran en el mismo directorio de la clase actual. Por ejemplo:

a.class 
CallablePrintTask.class 
java.policy.applet 
RunnablePrintTask.class 
ZoomableImageFrame.class 
ZoomableImageFrame$FlagHolder.class 
ZoomableImageFrame$ImageViewer.class 
ZoomableImageFrame$LoadAction.class 
ZoomableImageFrame$LoadAction$1.class 
ZoomableImageFrame$ScaleAction.class 
+0

Buena ilustración de lo que está pasando. Supongo que la razón por la que recibí una transmisión vacía en lugar de resultados como este tiene algo que ver con probar mis hipótesis en la consola Groovy ... –

0

Mi opinión es la siguiente:

this.class.getResourceAsStream("no_such_resource"); // returns null 
this.class.getResourceAsStream("");     // returns an InputStream 
this.class.getResourceAsStream(" ");    // returns an InputStream 
this.class.getResourceAsStream("\t"); 

getResourceAsStream("c:\t") < - es válida.

Es una coincidencia que \t es un carácter de tabulación. Sin embargo, es perfectamente válido tener eso como un camino para buscar.

+0

No lo creo. Para hacer una cadena de Java válida de una ruta delimitada por barra invertida, tendría que escapar de las barras diagonales inversas. En otras palabras, tendrías que hacer esto 'getResourceAsStream (" c: \\ t ")'. No es lo mismo que un carácter de tabulación en absoluto. – Stewart

Cuestiones relacionadas