Konvertiere eine SEHR GROSSE Binärdatei in eine Base64String inkrementell

7

Ich brauche Hilfe beim Umwandeln einer SEHR GROSSEN Binärdatei (ZIP-Datei) in einen Base64String und wieder zurück. Die Dateien sind zu groß, um sie alle gleichzeitig in den Speicher zu laden (sie werfen OutOfMemoryExceptions aus), sonst wäre dies eine einfache Aufgabe. Ich möchte den Inhalt der ZIP-Datei nicht einzeln verarbeiten, ich möchte die gesamte ZIP-Datei verarbeiten.

Das Problem:

Ich kann die gesamte ZIP-Datei (Testgrößen variieren von derzeit 1 MB bis 800 MB) in Base64String konvertieren, aber wenn ich sie zurück konvertiere, ist sie beschädigt. Die neue ZIP-Datei hat die richtige Größe, sie wird von Windows und WinRAR / 7-Zip usw. als ZIP-Datei erkannt, und ich kann sogar in die ZIP-Datei schauen und den Inhalt mit den richtigen Größen / Eigenschaften sehen, aber wann Ich versuche, aus der ZIP-Datei zu extrahieren, bekomme ich: "Fehler: 0x80004005" das ist ein allgemeiner Fehlercode.

Ich bin mir nicht sicher, wo oder warum die Korruption passiert. Ich habe einige Nachforschungen angestellt, und mir ist Folgendes aufgefallen:

Wenn Sie eine große Textdatei haben, können Sie sie inkrementell ohne Probleme in Base64String konvertieren. Wenn Convert.ToBase64String für die gesamte Datei aufgerufen würde: "abcdefghijklmnopqrstuvwx" , würde das Aufrufen der Datei in zwei Teilen ergeben: "abcdefghijkl" und "mnopqrstuvwx ".

Wenn die Datei eine binäre Datei ist, ist das Ergebnis leider anders. Während die gesamte Datei möglicherweise Folgendes liefert: "abcdefghijklmnopqrstuvwx" , würde der Versuch, dies in zwei Teilen zu verarbeiten, zu folgendem Ergebnis führen: "oiweh87yakgb" und "kyckshfguywp" .

Gibt es eine Möglichkeit, inkrementell eine 64-Bit-Datei zu codieren, während diese Korruption vermieden wird?

Mein Code:

%Vor%

Die Decodierung ist mehr von der gleichen. Ich benutze die Größe der Variablen base64String (die von der ursprünglichen Puffergröße abhängt, mit der ich teste) als Puffergröße für die Decodierung. Dann, anstelle von Convert.ToBase64String() , rufe ich Convert.FromBase64String() auf und schreibe in einen anderen Dateinamen / -pfad.

BEARBEITEN:

In meiner Eile, den Code zu reduzieren (ich habe ihn in ein neues Projekt umstrukturiert, von anderen Prozessen getrennt, um Code zu eliminieren, der für das Problem nicht von zentraler Bedeutung ist), habe ich einen Bug eingeführt. Die base 64-Konvertierung sollte für alle Iterationen am secondaryBuffer durchgeführt werden, die letzte (Identified by isFinalChunk ), wenn buffer verwendet werden soll. Ich habe den obigen Code korrigiert.

EDIT # 2:

Vielen Dank für Ihre Kommentare / Rückmeldungen. Nachdem ich den Fehler korrigiert habe (siehe oben), habe ich meinen Code erneut getestet und er funktioniert jetzt. Ich beabsichtige, @ renes Lösung zu testen und zu implementieren, da sie die beste Lösung zu sein scheint, aber ich dachte, dass ich auch alle meine Entdeckung wissen lassen sollte.

    
CaptainCobol 21.09.2015, 19:20
quelle

3 Antworten

10

Basierend auf dem Code, der in dem Blog von Wiktor Zychla der folgende Code funktioniert. Dieselbe Lösung wird im Abschnitt Anmerkungen von Convert.ToBase64String angezeigt wie von Ivan Stoev

hervorgehoben %Vor%

Der Code verwendet Standardklassen, die in System zu finden sind .Security.Cryptography Namespace und verwendet eine CryptoStream und die FromBase64Transform und sein Gegenstück ToBase64Transform

    
rene 21.09.2015, 20:12
quelle
8

Sie können vermeiden, einen sekundären Puffer zu verwenden, indem Sie Offset und Länge an Convert.ToBase64String übergeben, wie folgt:

%Vor%

Das obige sollte funktionieren, aber ich denke, Renes Antwort ist eigentlich die bessere Lösung.

    
Blorgbeard 21.09.2015 19:45
quelle
1

Verwenden Sie diesen Code:

%Vor%     
Yacoub Massad 21.09.2015 19:56
quelle

Tags und Links