Der Delphi-Treff-Code ist scheinbar extrem fehlerhaft. Bin gerade dabei das Archiv zu öffnen. Mit dem Originalcode kam es sofort zu der schönen Fehlermeldung "Versuch hinter dem Dateiende zu lesen." Bei dem Versuch diesen Fehler auszubügeln sind mir ein paar merkwürdige Sachen aufgefallen. Die Variable AktPos ist unnötig, denn es gibt die Funktion FilePos. Folgende If bügelt den Fehler an sich schon aus:
Delphi-Quellcode:
if FileSize(Archiv.Archiv) < (SSize+Sizeof(SSize)*2 + Size) then
Exit;
Zu beachten dabei ist, dass ich einiges umbenannt habe:
Delphi-Quellcode:
type
TArchiv = record
Archiv : File;
Dateibeginn : TStringList;
Dateinamen : TStringList;
end;
procedure SchreibeArchiv(Name, Dateiname, NameImArchiv : String);
procedure OeffneArchiv(Name : String; var Archiv : TArchiv);
procedure SchliesseArchiv(var Archiv : TArchiv);
procedure LeseArchiv(Archiv : TArchiv; Neu : String; Nummer: Integer);
Seek ist denke ich unnötig, denn die Position verändert sich nicht.
Aber damit ihr nun versteht, wovon ich überhaupt rede, hier der Originalcode (Bezeichner sind an meine angepasst):
Delphi-Quellcode:
procedure OeffneArchiv(Name : String; var Archiv : TArchiv);
var Size : Longint;
AktPos : Integer;
s : String;
SSize : Byte; // Länge des Strings
begin
Archiv.Dateibeginn := TStringList.Create;
Archiv.Dateinamen := TStringList.Create;
if not FileExists(Name) then
Exit;
AssignFile(Archiv.Archiv, Name);
Reset(Archiv.Archiv, 1);
// Erste Datei
BlockRead(Archiv.Archiv, SSize, SizeOf(SSize));
// Größe des Dateinamen auslesen
SetLength(s,SSize);
// S die Länge zuweisen
BlockRead(Archiv.Archiv, s[1], SSize);
// Dateiname auslesen
BlockRead(Archiv.Archiv, Size, SizeOf(Size));
// Dateigröße
Archiv.Dateinamen.Add(s);
// Dateiname
Archiv.Dateibeginn.Add(IntToStr(SSize+SizeOf(SSize)+SizeOf(Size)));
// Beginn der ersten Daten der ersten Datei, +Size weil man sich nun am Anfang der zweiten Datei befindet
AktPos := SSize+SizeOf(SSize)+SizeOf(Size)+Size;
// Alle Dateien durchlaufen
while AktPos+1 < FileSize(Archiv.Archiv) do
begin
Seek(Archiv.Archiv, AktPos);
BlockRead(Archiv.Archiv, SSize, SizeOf(SSize));
SetLength(s, SSize);
BlockRead(Archiv.Archiv, s[1], SSize);
BlockRead(Archiv.Archiv, Size, SizeOf(Size));
AktPos := AktPos+SizeOf(SSize)+SSize+SizeOf(Size);
Archiv.Dateinamen.Add(s);
Archiv.Dateibeginn.Add(IntToStr(AktPos));
AktPos := AktPos + Size;
end;
end;
Und hier mein eigener aktueller Code, welcher zu funktionieren scheint, aber schaut bitte nochmal drüber ob da Fehler drinnen sind, man kann ja nie wissen:
Delphi-Quellcode:
procedure OeffneArchiv(Name : String; var Archiv : TArchiv);
var Size : Longint;
s : String;
SSize : Byte; // Länge des Strings
begin
Archiv.Dateibeginn := TStringList.Create;
Archiv.Dateinamen := TStringList.Create;
if not FileExists(Name) then
Exit;
AssignFile(Archiv.Archiv, Name);
Reset(Archiv.Archiv, 1);
if FileSize(Archiv.Archiv) < (SSize+Sizeof(SSize)*2 + Size) then
Exit;
// Erste Datei
BlockRead(Archiv.Archiv, SSize, SizeOf(SSize));
// Größe des Dateinamen auslesen
SetLength(s,SSize);
// S die Länge zuweisen
BlockRead(Archiv.Archiv, s[1], SSize);
// Dateiname auslesen
BlockRead(Archiv.Archiv, Size, SizeOf(Size));
// Dateigröße
Archiv.Dateinamen.Add(s);
// Dateiname
Archiv.Dateibeginn.Add(IntToStr(SSize+SizeOf(SSize)+SizeOf(Size)));
// Alle Dateien durchlaufen
while FilePos(Archiv.Archiv)+1 < FileSize(Archiv.Archiv) do
begin
BlockRead(Archiv.Archiv, SSize, SizeOf(SSize));
SetLength(s, SSize);
BlockRead(Archiv.Archiv, s[1], SSize);
BlockRead(Archiv.Archiv, Size, SizeOf(Size));
Archiv.Dateinamen.Add(s);
Archiv.Dateibeginn.Add(IntToStr(FilePos(Archiv.Archiv)));
end;
end;
Bei der Funktion ReadArchivFile oder LeseArchiv bei mir steige ich nicht richtig durch, denn sie gibt in keiner Form was zurück und sieht extrem nach Beta aus. Gehe mal davon aus, dass man den Buffer zurückgeben muss.