Du benötigst für jeden vorkommenden Anfangsbuchstaben eine Datei.
Je Zeile prüfst Du, ob es diese Datei gibt, öffnest oder erstellst sie, schreibst hinein und schließt sie.
Welche Anfangsbuchstaben vorkommen, lässt sich sicherlich ermitteln.
Im Zweifel ist das alles von
ASCII 32 bis 255. Vermutlich aber eher
ASCII 49 bis 57 (für die Ziffern 0 bis 9),
ASCII 65 bis 90 (für A bis Z) und
ASCII 97 bis 122 (für a bis z). Eventuell noch sowas wie -_.
Erstelle Dir einmalig diese Dateien, dann kannst Du schonmal je Zeile das
Delphi-Quellcode:
if FileExists(OFile) then
begin
assignFile (OutFile, OFile);
append(OutFile);
end
else
einsparen.
Bei 97 GB (104.152.956.928 Byte) mit einer (geratenen) durchschnittlichen Zeilenlänge von 256 Byte, entfallen damit ca. 406.847.488 Prüfungen, ob eine Datei existiert oder nicht. Bei einer Dauer dieser Prüfung von jeweils 0,01 Sekunden, ergäbe der Wegfall dieser Prüfungen eine Laufzeitverringerung von ca. 47 Tagen.
Bei 64 KB pro Zeile wäre das noch 'ne Ersparnis von etwa 4,5 Tagen.
Wenn Du Dir nun die Dateien am Programmanfang erstellst bzw. öffnest, sie während der Programmlaufzeit offen hälst und erst zum Programmende schließt, sparst Du auch noch die ReWrites und CloseFiles je Zeile. Könnte dann auch die Laufzeit spürbar verkürzen.
Eventuell könnte ja sowas in der Art funktionieren (ungetestet hingedaddelt):
Delphi-Quellcode:
type
rFile = record
AFile : TextFile;
AFileName : String;
end;
TFiles = Array[32..255] of rFile;
var
Files : TFiles;
procedure TForm1.cb3Click(Sender: TObject);
var
i : Integer;
sZeile : String;
inFile : TextFile;
begin
for i := Low(Files) to High(Files) do begin
Files[i].AFileName := Format('i:\rockyou2021-%.3d.txt',[i]);
AssignFile(Files[i].AFile,Files[i].AFileName);
case FileExists(Files[i].AFileName) of
true : Append(Files[i].AFile);
false : ReWrite(Files[i].AFile);
end;
end;
AssignFile(Infile,'I:\rockyou2022.txt');
Reset(Infile);
while not EoF(InFile) do begin
ReadLn(InFile, sZeile);
if sZeile <> '' then WriteLn(Files[Ord(sZeile[1])].AFile,sZeile);
end;
CloseFile(InFile);
for i := Low(Files) to High(Files) do CloseFile(Files[i].AFile);
end;