2010-09-14 5 views
10

Ich möchte mehrere Stream-Vorgänge verketten (z. B. das Herunterladen einer Datei, das Dekomprimieren der Datei im laufenden Betrieb und die Verarbeitung der Daten ohne temporäre Dateien). Die Dateien sind im 7z-Format. Es ist ein LZMA-SDK verfügbar, aber zwingt mich, einen externen Ausgabestrom zu erstellen, anstatt selbst ein Stream zu sein - mit anderen Worten, der Ausgabestrom muss vollständig geschrieben werden, bevor ich damit arbeiten kann. SevenZipSharp scheint diese Funktionalität ebenfalls zu vermissen.Behandeln von 7z-Dateien als .NET-Streams

Hat jemand so etwas getan?

// in pseudo-code - CompressedFileStream derives from Stream 
foreach (CompressedFileStream f in SevenZip.UncompressFiles(Web.GetStreamFromWeb(url)) 
{ 
    Console.WriteLine("Processing file {0}", f.Name); 
    ProcessStream(f); // further streaming, like decoding, processing, etc 
} 

Jede Datei-Stream wie ein Lese einmal verhalten würde eine Datei streamen darstellt, und ruft Movenext() auf dem Haupt komprimierten Strom automatisch ungültig machen würde & diese Datei überspringen.

Ähnliche Konstrukte können für die Komprimierung verwendet werden. Beispielverwendung - Aggregation für eine sehr große Datenmenge durchführen - für jede 7z-Datei in einem Verzeichnis für jede Datenzeile in jeder Datei einen Wert summieren.

UPDATE 2012-01-06

#ziplib (SharpZipLib) bereits tut genau das, was ich für Zip-Dateien mit ZipInputStream Klasse benötigen. Hier ist ein Beispiel, das alle Dateien als unsekable Streams innerhalb einer gegebenen Zip-Datei liefert. Immer noch auf der Suche nach 7z-Lösung.

IEnumerable<Stream> UnZipStream(Stream stream) 
{ 
    using (var zipStream = new ZipInputStream(stream)) 
    { 
     ZipEntry entry; 
     while ((entry = zipStream.GetNextEntry()) != null) 
      if (entry.IsFile) 
       yield return zipStream; 
    } 
} 

Antwort

0

Der zugrunde liegende Algorithmus und Parameter zum Zeitpunkt der Kompression festgelegt, die Größe der Stücke bestimmen und es gibt keinen Weg, um sicherzustellen, wie Sie Stücke entschlüsseln, sie an Wort-/Zeilengrenzen fallen. Daher müssen Sie eine Datei vor der Verarbeitung vollständig dekomprimieren.

Was Sie fragen, ohne temporäre Dateien wahrscheinlich nicht möglich ist, zu tun - was es hängt wirklich davon ab, ob Sie genügend Speicher haben die entpackte Datei öffnen über einen Memorystream zu halten, führen Sie alle Ihre Verarbeitung und lassen Sie dann die Speicher zurück zum Pool. Erschwerend kommt hinzu, dass die Fragmentierung (des Prozessspeichers) wiederholt dazu führen kann.

+0

Ich bin mir nicht sicher, ob ich verstehe, was Sie mit Wort/Linie Grenzen meinen. Das 'CompressedFileStream'-Objekt wird in dem Moment zurückgegeben, in dem SevenZip den Datei-Header aus dem Stream empfängt, nicht nachdem die gesamte Datei abgerufen wurde. Das Lesen dekomprimierter Dateidaten bewirkt, dass der Quelldatenstrom ebenfalls fortschreitet. – Yurik