Es gibt 5 riesige Dateien (Datei1, Datei2, .. Datei5) mit jeweils ca. 10 GB und extrem wenig freiem Speicherplatz auf der Festplatte, und ich muss alle diese Dateien zu einer zusammenfassen. Es ist nicht erforderlich, die Originaldateien zu behalten, sondern nur die endgültigen.
Übliche Verkettung mit wird cat
für Dateien in Folge file2
.. file5
:
cat file2 >> file1 ; rm file2
Leider erfordert dieser Weg mindestens 10 GB freien Speicherplatz, den ich nicht habe. Gibt es eine Möglichkeit, Dateien zu verketten, ohne sie tatsächlich zu kopieren, aber dem Dateisystem irgendwie mitzuteilen, dass Datei1 nicht am ursprünglichen Ende von Datei1 endet und beim Start von Datei2 fortgesetzt wird?
ps. Dateisystem ist ext4, wenn das wichtig ist.
filesystems
files
eilen
quelle
quelle
nbd-server
.Antworten:
AFAIK es ist (leider) nicht möglich, eine Datei von Anfang an abzuschneiden (dies kann für die Standardtools zutreffen, aber für die Syscall-Ebene siehe hier ). Mit etwas mehr Komplexität können Sie jedoch die normale Kürzung (zusammen mit Dateien mit geringer Dichte) verwenden: Sie können bis zum Ende der Zieldatei schreiben, ohne alle Daten dazwischen geschrieben zu haben.
Angenommen, beide Dateien haben genau 5 GB (5120 MB) und Sie möchten jeweils 100 MB verschieben. Sie führen eine Schleife aus
Kürzen der Quelldatei um einen Block (Freigeben von Speicherplatz)
Aber probieren Sie es zuerst mit kleineren Testdateien aus, bitte ...
Wahrscheinlich haben die Dateien weder die gleiche Größe noch ein Vielfaches der Blockgröße. In diesem Fall wird die Berechnung der Offsets komplizierter.
seek_bytes
undskip_bytes
sollte dann verwendet werden.Wenn dies der Weg ist, den Sie gehen möchten, aber Hilfe für die Details benötigen, dann fragen Sie erneut.
Warnung
Abhängig von der
dd
Blockgröße ist die resultierende Datei ein Fragmentierungs-Albtraum.quelle
Anstatt die Dateien zu einer Datei zusammenzufassen, können Sie auch eine einzelne Datei mit einer Named Pipe simulieren, wenn Ihr Programm nicht mehrere Dateien verarbeiten kann.
Wie Hauke vorschlägt, kann auch losetup / dmsetup funktionieren. Ein schnelles Experiment; Ich habe 'file1..file4' erstellt und mit ein wenig Mühe folgendes getan:
Dann enthält / dev / dm-0 ein virtuelles Blockgerät mit Ihrer Datei als Inhalt.
Ich habe das nicht gut getestet.
Eine weitere Änderung: Die Dateigröße muss gleichmäßig durch 512 teilbar sein, da sonst Daten verloren gehen. Wenn ja, dann bist du gut. Ich sehe, dass er das auch unten notiert hat.
quelle
dmsetup
zu einem virtuellen Block-Gerät zu kombinieren (das normale Suchvorgänge ermöglicht, aber weder anfügt noch abschneidet). Wenn die Größe der ersten Datei nicht ein Vielfaches von 512 ist, sollten Sie den unvollständigen letzten Sektor und die ersten Bytes aus der zweiten Datei (in Summe 512) in eine dritte Datei kopieren. Das Loop-Gerät für die zweite Datei würde--offset
dann brauchen .Sie müssen etwas schreiben, das Daten in Gruppen kopiert, die höchstens so groß sind wie der verfügbare Speicherplatz. Es sollte so funktionieren:
file2
(indem Siepread()
vor dem Lesen nach dem richtigen Speicherort suchen).file1
.fcntl(F_FREESP)
diese Option, um die Zuordnung des Speicherplatzes von aufzuhebenfile2
.quelle
fcntl(F_FREESP)
wodurch der mit einem bestimmten Byte-Bereich der Datei verknüpfte Speicherplatz freigegeben wird (wodurch die Datei sparsam wird).fcntl
Manpage (15.04.2012) nicht erwähnt .fallocate
. Neuere Versionen des Dienstprogramms fallocate fromutil-linux
haben eine Schnittstelle dazu.Ich weiß, es ist eher eine Problemumgehung als das, wonach Sie gefragt haben, aber es würde Ihr Problem lösen (und mit wenig Fragmentierung oder Kratzern):
und dann
oder, wenn Sie glauben, dass die Komprimierung helfen würde:
Dann (und NUR dann) endlich
quelle