2013-07-04 15 views
5

Il metodo getResourceAsStream restituisce null ogni volta che si esegue il jar eseguibile in una directory che termina con un punto esclamativo.Impossibile aprire le risorse nelle directory che terminano con un punto esclamativo (!)

Per il seguente esempio, ho un progetto Eclipse la seguente struttura di directory:

src\ (Source Folder) 
    main\ (Package) 
     Main.java 
    res\ (Source Folder) 
     images\ 
      Logo.png 

sto leggendo il Logo.png come segue:

public static void main(String[] args) throws IOException { 
    try (InputStream is = Main.class.getClassLoader().getResourceAsStream("images/Logo.png")) { 
     Image image = ImageIO.read(is); 
     System.out.println(image); 
    } 
} 

Vedi l'allegato per 2 di prova casi. Innanzitutto, il jar eseguibile viene avviato dalla directory "D: \ test123! @ #" Senza problemi. In secondo luogo, il jar eseguibile viene avviato dalla directory "D: \ test123! @ # !!!", con problemi.

Le directory che terminano con un punto esclamativo non sono supportate? Il codice è sbagliato?

Grazie in anticipo.

Error when running the executable jar in a directory ending with !

+0

C'è un motivo, è possibile creare/utilizzare le directory con nomi normali? – mtk

+0

Sei sicuro di aver inserito uguali vasi in entrambe le directory? – Andremoniy

+0

Gli utenti possono eseguire la mia applicazione da qualsiasi luogo sul proprio file system. Le directory con punti esclamativi sono supportate da Windows. – Velth

risposta

7

Probabilmente a causa di questo bug o uno qualsiasi dei molti bug simili nel database dei bug di Java: "/"

http://bugs.sun.com/view_bug.do?bug_id=4523159

La ragione è che in un URL barattolo viene interpretato come separatore tra il nome del file JAR e il percorso all'interno del JAR stesso. Se il nome di una directory termina con!, La sequenza di caratteri "! /" Alla fine della directory viene interpretata erroneamente. Nel tuo caso, in realtà si sta tentando di accedere a una risorsa con il seguente URL:

jar: file: /// D:!/Test1231 @ # !!! /test.jar /images/logo.png

Il bug è stato aperto per quasi 12 anni e non è probabile che venga risolto. In realtà non so come possa essere risolto senza rompere altre cose. Il problema è la decisione di progettazione da usare! come un personaggio con un significato speciale (separatore) nello schema di URL per file JAR:

jar:<URL for JAR file>!/<path within the JAR file> 

Dal momento che il punto esclamativo è un carattere ammesso negli URL, che può verificarsi sia nel URL al file JAR stesso, come così come nel percorso all'interno del file JAR, rendendo in alcuni casi impossibile trovare il vero separatore "! /".

+0

Ho pensato che doveva fare qualcosa con Java e analizzare gli URL con "! /", Ma semplicemente non potevo credere che questo sarebbe un bug Ad ogni modo, potrebbe esserci una soluzione per risolvere questo problema? – Velth

+0

No, come indicato anche nel bug a cui mi sono collegato, non esiste una soluzione banale per questo problema. – jarnbjo

1

Un lavoro semplice per Windows è utilizzare "\" invece di "/" nel percorso. Ciò significherebbe che la sequenza di caratteri "! /" Viene trovata dopo il percorso completo. Per esempio:

new URL("jar:file:\\d:\\[email protected]#!!!\\test.jar!/images/Logo.png"); 

My Code:

File jar = new File(jarPath + "/" + jarName); 
URL url = new URL("jar:" + jar.toURI() + "!" + dataFilePath); 
InputStream stream = null; 
try { 
    stream = url.openStream(); 
} catch (FileNotFoundException e) { 
    // Windows fix 
    URL urlFix = new URL("jar:" + jar.toURI().toString().replace('/', '\\') 
     + "!" + dataFilePath); 
    stream = urlFix.openStream(); 
} 

io uso touri() perché gestisce le cose come spazi.

Correzioni:

La correzione si sarebbe per Java per verificare se il file esiste e se non continuare con il prossimo separatore (la parte dell'URL "/") fino a quando i separatori sono esauriti, poi gettare l'eccezione. Quindi vedrebbe che "d: \ test1231 @ # !!" lancia una java.io.FileNotFoundException e quindi prova "d: \ test1231 @ # !!! \ test.jar" che esiste. In questo modo non importa se ci sono "!" nel percorso del file o nei file del jar.

In alternativa, "! /" Può essere convertito in qualcos'altro che è un nome di file non valido o qualcosa di specifico (come "jarpath:").

In alternativa, il percorso del file jar utilizza un altro parametro.

Nota:

Potrebbe essere possibile ignorare qualcosa, scambiare un gestore, o modificare il codice per aprire il file prima poi guardo dentro il file jar più tardi, ma non ho guardato.

Problemi correlati