2012-03-26 14 views
7

Ich habe ein ZIP-Archiv, das in eine größere Datei eingebettet ist. Ich kenne den Startoffset des Archivs innerhalb der größeren Datei und deren Länge.Lesen von Dateien aus einem eingebetteten ZIP-Archiv

Gibt es Java-Bibliotheken, die es mir ermöglichen, die im Archiv enthaltenen Dateien direkt zu lesen? Ich denke an die Linien ZipFile.getInputStream(). Leider funktioniert ZipFile nicht für diesen Anwendungsfall, da seine Konstruktoren eine eigenständige ZIP-Datei erfordern.

Aus Leistungsgründen kann ich das ZIP-Archiv nicht in eine separate Datei kopieren, bevor ich es öffne.

bearbeiten: Nur um klar zu sein, habe ich zufälligen Zugriff auf die Datei.

+0

'java.util.zip.ZipInputStream.ZipInputStream (InputStream)'? – artbristol

+0

Schwierig. Bei einer ZIP-Datei müssen Sie zuerst das Verzeichnis lesen, das sich am Ende befindet, so dass Sie einen wahlfreien Zugriff benötigen.Sie * könnten * alle Einträge auf einmal von Anfang an lesen, und das würde mit den meisten ZIP-Dateien funktionieren, aber das Format selbst ermöglicht lustige Dinge wie doppelte Einträge und zufällige Junk-Daten zwischen den Einträgen. – Thilo

+0

@Thilo: Nur um klar zu sein, ich habe zufälligen Zugriff auf die Datei. – NPE

Antwort

6

Ich habe einen schnellen Hack gefunden (der hier und da bereinigt werden muss), liest aber den Inhalt von Dateien aus einem ZIP-Archiv, das in eine TAR eingebettet ist. Es verwendet Java6, FileInputStream, ZipEntry und ZipInputStream. 'Arbeiten auf meinem lokalen Rechner':

final FileInputStream ins = new FileInputStream("archive.tar"); 
// Zip starts at 0x1f6400, size is not needed 
long toSkip = 0x1f6400; 
// Safe skipping 
while(toSkip > 0) 
    toSkip -= ins.skip(toSkip); 

final ZipInputStream zipin = new ZipInputStream(ins); 
ZipEntry ze; 
while((ze = zipin.getNextEntry()) != null) 
{ 
    final byte[] content = new byte[(int)ze.getSize()]; 
    int offset = 0; 
    while(offset < content.length) 
    { 
     final int read = zipin.read(content, offset, content.length - offset); 
     if(read == -1) 
      break; 
     offset += read; 
    } 
    // DEBUG: print out ZIP entry name and filesize 
    System.out.println(ze + ": " + offset); 
} 
zipin.close(); 
1

1.create FileInputStream fis = neuer FileInputStream (..);

  1. Position es zu Beginn des eingebetteten zipfile: fis.skip (Offset);

  2. offen ZipInputStream (fis)

+0

das sollte für die meisten Dateien funktionieren, aber das Zip-Dateiformat erlaubt seltsame Dinge wie doppelte Einträge und zufällige Junk-Daten zwischen den Einträgen, also wäre es besser, einen zufälligen Zugriff zu haben und das Verzeichnis am Ende des Archivs zuerst zu lesen. – Thilo

-1

7-zip-JavaBinding ist ein Java-Wrapper für die C++ - Bibliothek 7-zip.

Die Seite code snippets hat insbesondere einige schöne Beispiele, darunter das Drucken einer Liste von Elementen in einem Archiv, das Extrahieren einer einzelnen Datei und das Öffnen von mehrteiligen Archiven.

-1

Überprüfen Sie, ob zip4j hilft Ihnen, oder nicht.

Sie können versuchen, PartInputStream lesen Zip-Datei nach Ihrem Anwendungsfall.

Ich denke, es ist besser, temporäre Zip-Datei zu erstellen und dann darauf zuzugreifen.

1

Ich empfehle mit TrueZIP, bietet es Dateisystemzugriff auf viele Arten von Archiven. Es hat in der Vergangenheit gut für mich funktioniert.

0

Ich denke, Apache Commons komprimieren kann Ihnen helfen.

Es gibt eine Klasse org.apache.commons.compress.archivers.zip.ZipArchiveEntry, die java.util.zip.ZipEntry erben.

Es hat eine Methode getDataOffset(), die den Offset des Datenstroms innerhalb der Archivdatei erhalten kann.

Verwandte Themen