2012-07-13 3 views
5

Je viens de rencontrer un comportement particulier avec getResourceAsInputStream que j'espérais que quelqu'un pourrait faire la lumière.Pourquoi getResourceAsStream avec une chaîne vide retourne un InputStream vide?

En passant cette méthode, le nom d'une ressource inexistante renvoie null, comme je le pensais. Toutefois, en lui passant une chaîne vide ou espace-rempli renvoie réellement un InputStream valide avec zéro octets en elle. Seules les chaînes vides ou remplies d'espace semblent le faire; Les espaces comme "\ t" ou "\ n" donneront une valeur nulle.

Est-ce un comportement prévu? Si oui, quel est son but?

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 

Répondre

3

getResourceAsStream demande à ClassLoader de construire une URL pour le chemin. Le chemin avec une chaîne vide ou des espaces vides à l'extrémité pointe vers le répertoire des fichiers où se trouve votre fichier classes .class, afin qu'il construise un objet FileURLConnection. getResourceAsStream à son tour demande cet objet à getInpuStream() et l'implémentation crée une liste de répertoires triés dans une chaîne, la convertit en octets en fonction des paramètres régionaux par défaut et vous donne un ByteArrayInputStream sur ces octets.

comportement

FileURLConnections est pas très bien documenté, mais si votre recherche ...

+1

Bonne explication! Il est à noter qu'il s'agit d'une anomalie de 'FileURLConnection' qui n'est pas partagée par' JarURLConnection'; courir exactement le même code, mais avec les classes emballées dans un pot, ne produira pas une liste (selon mes tests, au moins). –

+0

Aha, ça a du sens! Merci pour l'explication. –

4

Essayez ce code:

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(); 

ceci affichera une liste des classes qui se trouvent dans le même répertoire de la classe actuelle. Par exemple:

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

Bonne illustration de ce qui se passe. Je suppose que la raison pour laquelle je recevais un flux vide au lieu de résultats comme ceci a quelque chose à voir avec le test de mes hypothèses dans la console Groovy .... –

0

Je pense est la suivante:

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") < - est valide.

C'est une coïncidence que \t est un caractère de tabulation. Pourtant, il est parfaitement valable d'avoir cela comme un chemin à rechercher.

+0

Je ne pense pas. Pour créer une chaîne Java valide d'un chemin délimité par une barre oblique inverse, vous devez échapper les barres obliques inverses. En d'autres termes, vous devrez faire ceci 'getResourceAsStream (" c: \\ t ")'. Ce n'est pas du tout la même chose qu'un caractère de tabulation. – Stewart

Questions connexes