Vor einer Datei mit mehreren Gigabyte

8

Was wäre der performanteste Weg, um ein einzelnes Zeichen einer Datei mit mehreren Gigabyte vorzugeben (in meinem praktischen Fall eine Datei mit 40 GB).

Es gibt keine Beschränkung für die Implementierung, dies zu tun. Das heißt, es kann durch ein Werkzeug, ein Shell-Skript, ein Programm in einer beliebigen Programmiersprache, ... sein.

    
dafmetal 22.04.2010, 12:45
quelle

9 Antworten

6

Es gibt keine wirklich einfache Lösung. Es gibt keine Systemaufrufe zum Voranstellen von Daten, nur anhängen oder neu schreiben.

Aber je nachdem, was Sie mit der Datei machen, kommen Sie vielleicht mit Tricks davon. Wenn die Datei sequenziell verwendet wird, können Sie eine benannte Pipe erstellen und cat onecharfile.txt bigfile > namedpipe eingeben und dann "namedpipe" als Datei verwenden . Dasselbe kann durch cat onecharfile.txt bigfile | program erreicht werden, wenn Ihr Programm stdin als Eingabe akzeptiert.

Für den wahlfreien Zugriff könnte ein Dateisystem FUSE verwendet werden, aber wahrscheinlich ist es zu kompliziert dafür.

Wenn du deine Hände richtig dreckig machen willst, dann probiere es einfach aus.

  • Zuweisen eines Datenblocks ( über die Inode- und Datenblockstruktur )
  • füge es als zweiten Block in eine Dateikette ein (oder zuerst und dann bist du praktisch fertig)
  • schreibe den Anfang der Datei in diesen Block
  • schreibe das einzelne Zeichen als erstes in die Datei
  • markiert den ersten Block so, als ob er nur ein Byte der verfügbaren Nutzdaten verwendet (dies ist für letzten Block möglich, ich weiß nicht, ob es für Blöcke in der Mitte der Dateikette möglich ist).

Dies hat jedoch die Möglichkeit, Ihr Dateisystem erheblich zu zerstören, also nicht empfohlen; viel Spaß.

    
Pasi Savolainen 22.04.2010, 13:27
quelle
3

Lassen Sie die Datei einen Anfangsblock aus Nullzeichen haben. Wenn Sie ein Zeichen vorgeben, lesen Sie den Block, fügen Sie das Zeichen von rechts nach links ein und schreiben Sie den Block zurück. Wenn der Block voll ist, führen Sie das teurere vollständige Neuschreiben aus, um einen weiteren Nullblock voranzustellen. Auf diese Weise können Sie die Anzahl der Male um einen großen Faktor reduzieren, den Sie vollständig neu schreiben müssen.

Hinzugefügt: Bewahren Sie die Datei in zwei Unterdateien auf: A (kurz) und B (lang). Gehen Sie nach A vor, wie Sie möchten. Wenn A "groß genug" wird, wird A nach B vorangestellt (durch erneutes Schreiben) und A wird gelöscht.

Ein anderer Weg: Bewahren Sie die Datei als Verzeichnis kleiner Dateien auf ..., A000003, A000002, A000001.
Stellen Sie einfach die Datei mit der größten Nummer voran. Wenn es groß genug ist, mach die nächste Datei der Reihe nach.
Wenn Sie die Datei lesen müssen, lesen Sie sie alle in absteigender Reihenfolge.

    
Mike Dunlavey 22.04.2010 14:06
quelle
1

Sie können Ihre Implementierung je nach Problem möglicherweise invertieren: Hängen Sie einzelne Zeichen an das Ende Ihrer Datei an. Wenn es an der Zeit ist, die Datei zu lesen, lesen Sie sie in reverse .

Verstecke dies hinter genug einer Abstraktionsschicht und es mag deinem Code keinen Unterschied machen, wie die Bytes physikalisch gespeichert sind.

    
Craig Walker 22.04.2010 14:24
quelle
0

Wenn Sie meinen, dass das Zeichen dem Anfang der gesamten Datei vorangestellt werden soll,

%Vor%

oder mit sed

%Vor%

wenn Sie meinen, dass das Zeichen jeder Zeile der Datei vorangestellt wird

%Vor%     
ghostdog74 22.04.2010 12:54
quelle
0

Wie ich verstehe, wird dies auf der Dateisystemebene gehandhabt. Wenn Sie also Daten einer Datei voranstellen, schreibt sie die Datei effektiv neu. Dies ist der gleiche Grund, warum die ID3-Tags in MP3-Dateien mit Nullen aufgefüllt werden, so dass zukünftige Updates nicht die gesamte Datei neu schreiben, sondern nur diese reservierten Bytes aktualisieren.

Also, was auch immer Sie verwenden, wird ungefähr ähnliche Ergebnisse geben. Was Sie ausprobieren können, ist einige Tests mit einer benutzerdefinierten Kopierfunktion durchzuführen, die in größeren Blöcken liest / schreibt als die Standardsystemkopie, sagen wir 2MB oder 5MB, was die Leistung verbessern könnte. Letztendlich ist Ihre Festplatten-I / O hier der Flaschenhals.

    
invert 22.04.2010 12:57
quelle
0

Vielleicht müssen Sie den Characer nicht physisch an die Datei anhängen, sondern nur virtuell. Möge es einen Dateisystemtreiber geben, der in der Lage ist, mehrere Dateien (1 Byte + 40 GB) virtuell in eine einzige virtuelle Datei zu mappen.

    
codymanix 22.04.2010 13:35
quelle
0

Hier ist die Windows-Befehlszeile ("DOS") Weg:

Setze dein 1 Char in prepend.txt

%Vor%     
Dinah 22.04.2010 14:13
quelle
0

Der absolut leistungsstärkste Weg scheint es zu sein, in die Ebene der Sektoren zu gelangen und wie die Datei tatsächlich gespeichert wird. Ich bin mir nicht sicher, ob das Betriebssystem dann ein Faktor wird, aber die Zielplattform könnte es sein, trotzdem ist es nützlich für uns, zu wissen, auf was Sie laufen.

Ich denke, das ist ein Fall, in dem C die offensichtliche Wahl ist, diese Art von Low-Level-Zeug ist genau das, was eine Systemprogrammiersprache für ist.

Können Sie uns sagen, was Sie tun, wäre interessant.

    
Mr. Boy 22.04.2010 14:19
quelle
0

Wenn Sie Linux verwenden, könnten Sie versuchen, eine benutzerdefinierte Version von READ (2) zu verwenden, die mit LD_PRELOAD geladen ist und Ihre Daten beim ersten Lesen vorlegt.

Siehe Ссылка zur Implementierung.

    
Darwin 31.08.2015 22:16
quelle

Tags und Links