2014-06-17 9 views
5

Ich habe derzeit ein plausibles Ressourcenleck in meiner Bibliothek aufgrund der Tatsache, dass ich eine ZipFile geöffnet halte, so dass der zurückgegebene InputStream für einen bestimmten ZipEntry nicht geschlossen ist. Schließen des zurückgegebenen InputStream schließt jedoch nicht den Rest der Zip-Datei, also bleibe ich dabei offen. Gibt es eine Möglichkeit, die Zip-Datei sicher zu schließen und den InputStream für die Rückgabe zu behalten?Bleibt ein ZipEntry bestehen, nachdem ein ZipFile geschlossen wurde?

Antwort

4

Hier ist die Implementierung von InputStream from ZipFile:

/* 
* Inner class implementing the input stream used to read a 
* (possibly compressed) zip file entry. 
*/ 
private class ZipFileInputStream extends InputStream { 

    ... 

    public int read(byte b[], int off, int len) throws IOException { 
     if (rem == 0) { 
      return -1; 
     } 
     if (len <= 0) { 
      return 0; 
     } 
     if (len > rem) { 
      len = (int) rem; 
     } 
     synchronized (ZipFile.this) { 
      ensureOpenOrZipException(); 

Beachten Sie den Aufruf an #ensureOpenOrZipException.

Also die Antwort auf Ihre Frage ist leider nein, es gibt keine Möglichkeit, den Stream offen zu halten.

Was man stattdessen tun könnte, ist wickeln und die # Schließen auf der Input Haken Ihre Zip-Datei zu schließen:

InputStream zipInputStream = ... 
return new InputStream() { 
    @Override 
    public int read() throws IOException { 
     return zipInputStream.read(); 
    } 
    @Override 
    public void close() throws IOException { 
     zipInputStream.close(); 
     zipFile.close(); 
    } 
} 

Ein anderer Ansatz wäre es zu puffern:

InputStream myZipInputStream = ... 
//Read the zip input stream fully into memory 
byte[] buffer = ByteStreams.toByteArray(zipInputStream); 
zipFile.close(); 
return new ByteArrayInputStream(buffer); 

Offensichtlich hat Jetzt sind alle in den Speicher gegangen, also müssen Ihre Daten eine angemessene Größe haben.

+0

Das ist ein bisschen wie ein Hack, aber es funktioniert! –

+0

Warum ist es ein Hack? Es ist eine einfache Kapselung des Zip #close. Ich fügte einen weiteren Ansatz hinzu, der mein erster Gedanke war, aber er verwendet einen Speicherpuffer, der für Sie möglicherweise nicht funktioniert. – Kong

+0

Als ich den Code betrachtete, erkannte ich, dass 'getInputStream' nur einen InputStream zurückgibt, ich dachte, dass es genauer wäre. Es ist dann kein Hack! –

Verwandte Themen