2011-01-14 4 views
3

Ich erstelle einen binären Editor für einige sehr große Binärdateien. Eine der Softwareanforderungen besteht darin, dass der Editor die ursprüngliche Datei nicht ändern kann, sodass die Zieldatei eine bearbeitete Kopie des Originals sein muss.Ein Transaktionsmodell zum Bearbeiten großer Binärdateien

Ich möchte den Editor so gestalten, dass das Kopieren der Datei nur einmal erfolgt (es wird ein 20-minütiger Prozess). Ich weiß, dass ich die Datei während der Bearbeitung sperren kann, aber wenn der Benutzer das Programm beendet, müssen sie den gesamten 20-minütigen Kopiervorgang noch einmal durchlaufen, es sei denn, ich finde einen Weg, um festzustellen, dass sie noch da sind ihre ursprüngliche Bearbeitungssitzung.

Gibt es einen einfachen Prozess, den Sie sich vorstellen können, mit dem ich dem Benutzer erlauben kann, die kopierte Datei irgendwie als editierbare Datei zu registrieren, und wenn sie mit all ihren Änderungen abgeschlossen sind, "finalisieren" Sie die Datei?

Idealerweise ein solcher Prozess würde mich erlauben erkennen, ob die editierbare Datei oder die Transaktionsinformationen mit in-zwischen Bearbeitungssitzungen (Manipulation oder Finalisierung verursachen würde eine weitere Kopie auftreten manipuliert wurde, wenn die Datei wieder bearbeitet).

Antwort

1
  1. Erstellen und verwalten Sie einen Datensatz (db?) Von Sitzungen an einem zentralen Ort.
  2. Sitzung besteht aus Benutzername, wenn Sie es haben, oder IP, oder was auch immer Sie verwenden möchten, um den Benutzer eindeutig zu identifizieren, und einen Hash der Bytes. Wenn Hash für die Dateigröße zu aufwändig ist, können Sie versuchen, sich auf das Datum und die Größe der Datei zu verlassen.
  3. Wenn der Benutzer seinen Editor schließt, aktualisieren Sie den Sitzungsdatensatz mit den obigen Informationen und markieren Sie ihn als inaktiv.
  4. Wenn der Benutzer den Editor erneut öffnet, sollten Sie Zugriff auf Ihre Schlüsselinformationen haben, z. B. den Benutzernamen und die Dateiinformationen. Wenn Sie einen Sitzungsdatensatz finden, handelt es sich um eine inaktive Sitzung, die Sie reaktivieren können, da sie sonst manipuliert wurde oder brandneu ist.

Passt das zu Ihren Bedürfnissen?

+0

Danke. Es stellt sich heraus, dass das binäre Dateiformat ein Flag enthält, das anzeigt, ob es sich um eine Kopie handelt, also werde ich einfach dieses Flag umdrehen. –

+0

Ist das nicht etwas, das manipuliert werden könnte? –

+0

Ja, aber es ist Teil der Dateispezifikation und ich werde nicht zulassen, dass sie es in meinem Editor bearbeiten. –

1

Ich denke, Sie wollen ein Protokoll über die vom Benutzer durchgeführten Aktionen protokollieren. Um das Schreiben in die Kopie der Quelldaten zu vermeiden, würde ich das Protokoll in einer separaten Datei aufbewahren. Speichern Sie die Bearbeitungen des Benutzers mit Zeitstempelinformationen.

Wenn es Zeit ist, die Transaktion zu committen, lesen Sie einfach die Liste der Änderungen in der Protokolldatei und wenden Sie sie an, geordnet nach Zeitstempel.

Wenn der Benutzer während des Bearbeitungsprozesses Daten aus der Datei lesen muss, müssen Sie den relevanten Teil der Quelldatei in den Speicher einlesen und die Änderungen an diesen Daten aus der Protokolldatei übernehmen.

Dies könnte wirklich der schwierigste Teil sein, abhängig vom binären Dateiformat. Wenn Sie die Inhalte der Binärdatei irgendwie indizieren können, würde ich diese Informationen im Bearbeitungsprotokoll verwenden. Auf diese Weise können Sie nur die benötigten Daten aus der Protokolldatei abrufen, und Sie können bestimmen, welche Änderungen für diese Daten gelten.

Wenn alles, was Sie haben, ein großer, formloser Blob ist, müssen Sie das gesamte Ding im Speicher behalten und alle Änderungen bei jedem Lesevorgang anwenden. Es gibt Raum für Optimierung, denke ich, aber das Ganze ist immer noch wirklich abscheulich. Ohne den Umfang des Lesens einschränken zu können, müssen Sie davon ausgehen, dass jede Änderung jederzeit die Daten ändern kann.

Um die Änderungen zu sichern, ist das eine knifflige Frage.Wenn Sie in einer Umgebung arbeiten, der Sie vertrauen, können Sie damit fortfahren, ein Geheimnis zu bewahren und die Informationen zu authentifizieren. Es ist umständlich, aber Sie könnten die Verkettung der Binärdatei, das Bearbeitungsprotokoll und ein Geheimnis, das nur der Anwendung bekannt ist, hashen. (Ohne das Geheimnis könnte irgendjemand vorbeikommen, die Datei ändern und einen neuen Hash einfügen.)

Wenn Sie auf einem Computer lokal für den Benutzer (dh einen Desktop) laufen, kann es sehr schwierig sein, Geheimnisse zu bewahren insbesondere mit verwaltetem Code. Dies ist ein Thema für sich selbst, und ich habe keine gute Antwort für Sie.

+0

Danke. Ich habe über die Idee der "Liste der Veränderungen" nachgedacht; das könnte immer noch nützlich sein, wenn ich die Undo/Redo-Funktionalität implementieren muss. –

1

Kannst du nicht einfach ein Feld in dieser Datei haben, mit festem Offset von Anfang oder Ende, wo du Sitzungsinformationen eingibst, nur ein 'bearbeite' Flag? Es kann einen Verweis auf seinen aktuellen Editierprozess (z. B. seine PID) enthalten. Wenn das Pid unser Pid ist, dann ist es unsere Sitzung. Wenn es nicht unsere PID ist, sehen Sie sich die Prozessliste an. Wenn ein Prozess mit dieser PID existiert, ist es der legitime Editor; Wenn nicht, sehen wir das Ergebnis eines Absturzes, initiieren eine Absturzwiederherstellung (falls vorhanden). Wenn pid 0 ist, wurde die Datei sauber finalisiert.

Auch: Wenn die große Datei zum Lesen verfügbar ist, müssen Sie sie wirklich kopieren, bevor Sie sie bearbeiten?

Wenn Änderungen im Vergleich zur Größe der Datei ziemlich klein sind, würde ich Benutzeraktionen als "Diffs" zwischen der Originaldatei und dem Ergebnis aufzeichnen. Wenn derselbe Spot immer wieder bearbeitet wird, kann es nützlich sein, die Diffs irgendwie zu "verbinden", so dass Sie nicht zu viele Diffs-Ebenen anwenden. Die Benutzeransicht der Datei wird natürlich mit allen Diffs dynamisch angewendet.

In der Zwischenzeit kopieren Sie die Datei, und sobald die Bearbeitungssitzung über und ist die Datei vollständig hier ist, wenden Sie alle Ihre Diffs auf die Datei. Je nach Art der zulässigen Bearbeitungen kann dies jedoch ein zeitaufwändiger Prozess sein oder auch nicht. Wenn Bearbeitungssitzungen länger als 20 Minuten sind, bemerkt der Benutzer möglicherweise überhaupt keine Wartezeit. Sie sperren die Datei für die Zeit der Diff-Anwendung, die vermutlich kürzer als die Kopierzeit ist.

1

Da Sie über Transaktionen und Dateisystemaktivitäten nachdenken, kann es hilfreich sein, Transactional NTFS in Betracht zu ziehen. Dies beantwortet Ihre Frage nicht, sondern gibt Ihnen möglicherweise einen neuen Einblick in die Möglichkeiten. Da Ihre Frage für C# und Windows getaggt ist, sollten Sie sich einen .NET-Wrapper wie hier anschauen: http://offroadcoder.com/CategoryView,category,Transactions.aspx. Scott Klueppel zeigt, wie man transaktionales NTFS mit dem vertrauten .NET-Idiom eines TransactionScope macht. Ich habe schnell getestet, was Scott getan hat und was ich gesehen habe.

Verwandte Themen