2014-11-14 27 views
6

E 'possibile, anche se forse mal consigliato, di leggere formati di archivio che sono fondamentalmente rinominato .zip file (.ear, .war, .jar, ecc), utilizzando il jar:URI scheme.Esistono java.net.URI validi per gli archivi nidificati?

Ad esempio, il seguente codice funziona bene quando la variabile uri viene valutata in un singolo archivio di primo livello, ad es. quando uri uguale jar:file:///Users/justingarrick/Desktop/test/my_war.war!/

private FileSystem createZipFileSystem(Path path) throws IOException { 
    URI uri = URI.create("jar:" + path.toUri().toString()); 
    FileSystem fs; 

    try { 
     fs = FileSystems.getFileSystem(uri); 
    } catch (FileSystemNotFoundException e) { 
     fs = FileSystems.newFileSystem(uri, new HashMap<>()); 
    } 

    return fs; 
} 

Tuttavia, le chiamate getFileSystem e newFileSystem falliscono con una IllegalArgumentException quando l'URI contiene gli archivi nidificati, ad esempio, quando uri è uguale a jar:jar:file:///Users/justingarrick/Desktop/test/my_war.war!/some_jar.jar!/ (a .jar all'interno di uno .war).

Esiste uno schema java.net.URI valido per i file di archivio nidificati?

+1

Dalla memoria, direi che la risposta è no. Java ha ancora bug non corretti riguardo all'escissione di '!' Negli URI (prova ad aggiungere quel botto alla fine di un nome di directory e poi aggiungendolo al tuo classpath) quindi la mia reazione istintiva è di dire che avrai del lavoro da fare per farlo funzionare nel modo desiderato. – ngreen

+1

Dal codice sorgente java (java.net.JarURLConnection), la risposta è anche no: 'int separator = spec.indexOf ("!/"); /* * RICORDA: non gestiamo gli URL JAR nidificati */ ... ' –

risposta

0

Come indicato nel commento di Jonas Berlin sopra, la risposta è no. Da java.net.JarURLConnection source:

/* get the specs for a given url out of the cache, and compute and 
* cache them if they're not there. 
*/ 
private void parseSpecs(URL url) throws MalformedURLException { 
    String spec = url.getFile(); 

    int separator = spec.indexOf("!/"); 
    /* 
    * REMIND: we don't handle nested JAR URLs 
    */ 
    if (separator == -1) { 
     throw new MalformedURLException("no !/ found in url spec:" + spec); 
    } 

    jarFileURL = new URL(spec.substring(0, separator++)); 
    entryName = null; 

    /* if ! is the last letter of the innerURL, entryName is null */ 
    if (++separator != spec.length()) { 
     entryName = spec.substring(separator, spec.length()); 
     entryName = ParseUtil.decode (entryName); 
    } 
}