Ich hab in den letzten paar Wochen nur wenig dran gemacht, aber jetzt hab ich ein Problem, das sehr seltsam ist.
Ich speichere die Daten jetzt typisiert, ich hab zwar noch nicht überprüft, ob die richtigen Daten in der richtigen Reihenfolge gespeichert werden, aber ich prüfe, ob Größe der Datei = Anzahl der gefundenen Dateien * Größe des Records. Das klappt, da (noch) die Datengröße statisch ist.
Jetzt passiert etwas Merkwürdiges: Wenn ich den Algo testweise auf ein kleines Verzeichnis (rund 100 Dateien und Ordner) anwende, ist die Datei so groß wie erwartet. Wende ich ihn jedoch auf größere Verzeichnisse an, ist die Datei größer als erwartet, es wurden also mehr Daten von Dateien eingetragen, als Dateien da sind
. Findet jemand den Fehler?
Die Dateien werden so eingelesen:
Delphi-Quellcode:
function TFiles.ReadFiles(Volume: String): Integer;
begin
//Variablen vorbereiten
FFileList := nil;
SetLength(FFileList, flInitialLength);
FFileListHighPos := -1;
FRootNode.Free;
FRootNode := TFileNode.Create;
//Suchvorgang starten
Result := RecurseProc(Volume, nil);
end;
Wobei RecurseProc so aussieht:
Delphi-Quellcode:
function TFiles.RecurseProc(Path: String; Node: TFileNode): Integer;
var
SearchRec: TSearchRec;
noFile: Boolean;
const
Mask = '*.*'; //die zur Dateisuche verwendete Maske (*.* für alle Dateien)
begin
Result := 0;
//sicherstellen, dass Pfad mit Backlash endet
if (Path[Length(Path)] <> '\') and (Path[Length(Path)] <> '/') then
Path := Path + '\';
if Node = nil then Node := FRootNode; //Standard-Rootnode setzen
if FindFirst(Path + Mask, faAnyFile, SearchRec) <> 0 then Exit;
//Suchschleife läuft als Endlosschleife, da vor UND nach Abbruchbedingung Code
//ausgeführt werden muss
while True do
begin
//prüfen auf Self- und Parent-Referenz
if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
noFile := False
else
noFile := True;
if not noFile then
begin
//falls Ordner gefunden wurde:
//- Zeiger auf erste ChildNode erstellen
//- weiter mit Dateien in diesem Ordner
if SearchRec.Attr and faDirectory = faDirectory then
begin
Node.FFirstChild := TFileNode.Create;
Result := Result + RecurseProc(Path + SearchRec.Name, Node.FFirstChild);
end;
//Datenrecord über Dateieintrag füllen
Node.FData.FullPath := Path + SearchRec.Name;
Node.FData.AbsIndex := FFileListHighPos + 1;
Node.FData.Size := SearchRec.Size;
//sicherstellen, dass das Array groß genug ist
EnsureListSize;
//Eintrag in Array eintragen
Inc(FFileListHighPos);
FFileList[FFileListHighPos] := Node;
Inc(Result);
end;
//nächstes Element suchen und prüfen auf Abbruchbedingung
if FindNext(SearchRec) <> 0 then Break;
if not noFile then
begin
//nur wenn ein nächstes Element vorhanden ist wird der Zeiger auf das nächste
//Element gesetzt
Node.FNext := TFileNode.Create;
Node := Node.FNext;
end;
end;
FindClose(SearchRec);
end;
Die Dateien werden so gespeichert:
Delphi-Quellcode:
class procedure TTreeFile.SaveToFile(RootNode: TTFNode; Filename: String);
var
FilePos: Integer;
procedure AddToStream(TFStream: TFileStream; Level: Word; TFNode: TTFNode);
var
Size: Word;
begin
//1. Schritt: Speichern der RootNode
Size := TFNode.GetData.Size;
TFStream.Position := FilePos;
TFStream.Write(Level, 2);
TFStream.Write(Size, 2);
TFStream.Write(TFNode.GetData.PData^, Size);
FilePos := TFStream.Position;
//2. Schritt: evtl. Aufruf mit dem ersten Kind
if TFNode.HasChildren then
begin
AddToStream(TFStream, Level + 1, TFNode.GetFirstChild);
end;
//3. Schritt: evtl. Aufruf mit dem nächsten Bruder
if TFNode.HasBrethren then
begin
AddToStream(TFStream, Level, TFNode.GetNext);
end;
end;
var
TFStream: TFileStream;
begin
TFStream := TFileStream.Create(Filename, fmCreate or fmShareDenyNone);
try
FilePos := 0;
AddToStream(TFStream, 0, RootNode);
finally
TFStream.Free;
end;
end;
Wär super, wenn mir jemand helfen könnte, da ich in dem Code keinen Fehler mehr entdecke (Speziell die Save-Prozedur ist interessant, denn die ReadFiles-Methode scheint soweit richtig zu sein.