Dateien splitten
Nicht immer passt eine Datei auf einen Datenträger. In diesem Fall muss man eine Datei in mehrere kleinere Dateien gesplittet werden. Die untenstehende Procedure erfüllt diese Aufgabe.
Sie erwartet drei Parameter. Dem ersten Parameter muss der Dateiname der Datei übergeben werden. Dem zweiten Parameter wird die maximale Größe eines Dateisegments übergeben. Soll man am Ende eine bestimmte Anzahl an Dateisegmenten erhalten, muss dies mithilfe des dritten Parameters gesteuert werden. Widersprechen sich MaxSize und FileCount hat MaxSize die höhere Priorität. Einer der Parameter sollte deshalb beim Aufruf auf 0 stehen.
uses math; procedure SplitFile(const Filename: string; MaxSize: longword; FileCount: longword); var f1, f2: TFileStream; i, j: integer; begin if (not FileExists(Filename)) or ((MaxSize = 0) and (FileCount = 0)) then exit; f1 := TFileStream.Create(Filename, fmOpenRead or fmShareDenyNone); try if MaxSize = 0 then MaxSize := ceil(f1.Size / FileCount); for i:=1 to ceil(f1.Size / MaxSize) do begin f2 := TFileStream.Create(Filename + Format('.%.3d', [i]), fmCreate or fmShareDenyWrite); try j := f1.Size - f1.Position; f2.CopyFrom(f1, min(MaxSize, j)); finally f2.Free; end; end; finally f1.Free; end; end;
Die gesplitteten Dateien werden im gleichen Verzeichnis abgespeichert, in dem sich auch die Quelldatei befindet. Bitte beachten Sie, dass TFileStream, den die Routine intern verwendet, mit großen Dateien über 2GB Probleme bekommt.
Die Routine kann so aufgerufen werden:
SplitFile('c:\Archiv.zip', 50000, 0);
Die Datei Archiv.zip wird nun in ca. 50 kB-Päckchen geteilt. Die Datei wird dabei nur geteilt, es wird kein neuer Header geschrieben. Die einzelnen Dateisegmente werden alleine höchstwahrscheinlich unbrauchbar sein. Die Namen der Dateisegmente werden nach folgendem Schema gebildet:
Archiv.zip.001 Archiv.zip.002 Archiv.zip.003