Schreiben in die Mitte der Datei (ohne Daten zu überschreiben)

8

In Windows ist es über eine API möglich, in die Mitte einer Datei zu schreiben, ohne Daten zu überschreiben und alles danach neu schreiben zu müssen?

Wenn es möglich ist, dann glaube ich, dass es die Datei fragmentieren wird; Wie oft kann ich es tun, bevor es zu einem ernsthaften Problem wird?

Wenn es nicht möglich ist, welcher Ansatz / Workaround normalerweise verwendet wird? Das erneute Schreiben aller Elemente nach dem Einfügepunkt wird mit großen (dh Gigabyte) Dateien wirklich schnell unmöglich.

Hinweis : Ich kann nicht vermeiden, in die Mitte schreiben zu müssen. Stellen Sie sich die Anwendung als Texteditor für riesige Dateien vor, in denen der Benutzer Dinge eingibt und dann speichert. Ich kann die Dateien auch nicht in mehrere kleinere teilen.

    
Andreas Bonini 07.03.2010, 21:53
quelle

6 Antworten

8

Ich kenne keine Möglichkeit, dies zu tun, wenn das Zwischenergebnis, das Sie benötigen, eine flache Datei ist, die von anderen Anwendungen als dem Editor verwendet werden kann. Wenn Sie eine Flat-Datei erstellen möchten, müssen Sie sie vom Änderungspunkt bis zum Ende der Datei aktualisieren, da es sich eigentlich nur um eine sequenzielle Datei handelt.

Aber die Kursivschrift ist aus gutem Grund da. Wenn Sie das Dateiformat steuern können, haben Sie einige Optionen. Einige Versionen von MS Word hatten eine Schnellspeicherfunktion, bei der sie das gesamte Dokument nicht neu geschrieben haben, sondern einen Delta-Datensatz an das Ende der Datei angehängt haben. Beim erneuten Lesen der Datei wurden dann alle Deltas der Reihe nach angewendet, so dass Sie die richtige Datei gefunden haben. Dies funktioniert natürlich nicht, wenn die gespeicherte Datei sofort für eine andere Anwendung verwendet werden muss, die das Dateiformat nicht versteht.

Was ich hier vorschlage, ist nicht , um die Datei als Text zu speichern. Verwenden Sie ein Zwischenformular, das Sie effizient bearbeiten und speichern können, und führen Sie dann einen Schritt aus, mit dem Sie das Formular selten in eine verwendbare Textdatei umwandeln können (z. B. beim Verlassen des Editors). Auf diese Weise kann der Benutzer so viel sparen, wie er möchte, aber die zeitaufwendige Operation wird nicht so viel bewirken.

Darüber hinaus gibt es einige andere Möglichkeiten.

Die Speicherzuordnung (anstatt die Datei zu laden) kann Effizienzen bieten, die die Dinge beschleunigen würden. Sie müssten wahrscheinlich noch am Ende der Datei neu schreiben, aber es würde auf einer niedrigeren Ebene im Betriebssystem passieren.

Wenn der Hauptgrund für die Schnellspeicherung darin besteht, dass der Benutzer weiterarbeiten kann (anstatt die Datei für eine andere Anwendung verfügbar zu haben), können Sie die Sicherungsoperation in einem separaten Thread speichern und die Steuerung sofort an den Benutzer zurückgeben. Dann müssten Sie die Synchronisierung zwischen den beiden Threads durchführen, um zu verhindern, dass der Benutzer die Daten noch auf dem Datenträger speichert.

    
paxdiablo 07.03.2010, 22:14
quelle
4

Die realistische Antwort lautet nein. Ihre einzige wirkliche Auswahl besteht darin, den Punkt der Änderung neu zu schreiben oder ein komplexeres Format zu erstellen, das so etwas wie einen Index verwendet, um zu erklären, wie Datensätze in der gewünschten Reihenfolge angeordnet werden sollen.

Aus rein theoretischer Sicht könnten Sie es unter den richtigen Umständen tun. Mit FAT (zum Beispiel, aber die meisten anderen Dateisysteme haben zumindest ein gewisses Maß an Ähnlichkeit) können Sie direkt in die FAT einsteigen. Die FAT ist im Grunde eine verknüpfte Liste von Clustern, aus denen eine Datei besteht. Sie können diese verknüpfte Liste ändern, um einen neuen Cluster in der Mitte einer Datei hinzuzufügen, und dann Ihre neuen Daten in den von Ihnen hinzugefügten Cluster schreiben.

Bitte beachten Sie, dass ich rein theoretisch gesagt habe. Diese Art der Manipulation unter einem kompletten ungeschützten System wie MS-DOS wäre schwierig gewesen, würde aber vernünftig sein. Bei den meisten neueren Systemen wäre es im Allgemeinen ziemlich schwierig, die Modifikation überhaupt durchzuführen. Die meisten modernen Dateisysteme sind (wesentlich) komplexer als FAT, was die Implementierung noch weiter erschweren würde. In der Theorie ist es immer noch möglich - in der Tat ist es jetzt völlig verrückt, sogar zu überlegen, wo es einmal fast vernünftig war.

    
Jerry Coffin 07.03.2010 22:18
quelle
2

Ich bin mir nicht sicher über das Format Ihrer Datei, aber Sie könnten es "aufzeichnen" basieren.

  • Schreiben Sie Ihre Daten in Chunks und geben Sie jedem Chunk eine ID.
  • Id könnte Datenoffset in Datei sein.
  • Am Anfang der Datei könnten Sie habe eine Kopfzeile mit einer Liste von IDs so dass Sie Datensätze lesen können bestellen.
  • Am Ende der 'Liste der IDs' können Sie auf eine andere Stelle in der Datei (und ID / Offset) zeigen, die eine andere Liste von IDs
  • speichert

Ähnliches Dateisystem.

Um neue Daten hinzuzufügen, fügen Sie sie am Ende an und aktualisieren den Index (fügen Sie der Liste ID hinzu).

Sie müssen herausfinden, wie Löschsatz und Update behandelt werden.

Wenn die Datensätze dieselbe Größe haben, können Sie sie zum Löschen einfach als leer markieren und das nächste Mal mit den entsprechenden Aktualisierungen der Indextabelle wiederverwenden.

    
stefanB 07.03.2010 22:15
quelle
0

Wenn Sie .NET 4 verwenden, versuchen Sie eine Memory-Mapped-Datei, wenn Sie eine editorähnliche Anwendung haben - könnte dies das Ticket sein. So etwas (ich habe es nicht in VS eingegeben, also nicht sicher, ob ich die Syntax richtig verstanden habe):

%Vor%     
Emmanuel 07.03.2010 22:18
quelle
0

Ich habe sowohl die Antwort von paxdiablo auf den Umgang mit anderen Anwendungen als auch den Kommentar von Matteo Italia zu Installable File Systems zur Kenntnis genommen. Das hat mir gezeigt, dass es eine andere nicht-triviale Lösung gibt.

Mit Analysepunkten können Sie eine "virtuelle" Datei aus einer Basisdatei plus Deltas erstellen. Jede Anwendung, die diese Methode nicht kennt, sieht einen fortlaufenden Bereich von Bytes, da die Deltas im laufenden Betrieb von einem Dateisystemfilter angewendet werden. Für kleine Deltas (insgesamt & lt; 16 KB) kann die Delta-Information in dem Analysepunkt selbst gespeichert werden; Größere Deltas können in einen alternativen Datenstrom eingefügt werden. Nicht-trivial natürlich.

    
MSalters 08.03.2010 15:19
quelle
0

Wahrscheinlich ist der effizienteste Weg (wenn Sie es wirklich wollen), ReadFileScatter() aufzurufen, um die Chunks vor und nach dem Einfügepunkt zu lesen. Fügen Sie die neuen Daten in die Mitte der FILE_SEGMENT_ELEMENT[3] -Liste ein und rufe WriteFileGather() auf. Ja, das beinhaltet das Verschieben von Bytes auf der Festplatte. Aber Sie überlassen die harten Teile dem OS.

    
MSalters 08.03.2010 15:04
quelle

Tags und Links