Thema: Delphi Eigenes Archivformat

Einzelnen Beitrag anzeigen

Nils_13

Registriert seit: 15. Nov 2004
2.647 Beiträge
 
#7

Re: Eigenes Archivformat

  Alt 1. Apr 2008, 21:49
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.
  Mit Zitat antworten Zitat