Home » Tutorials » Datenspeicherung » myArchiv

myArchiv

Archiv öffnen und schließen

Um anschließend eine Datei auslesen zu können, muss die entprechende Archivdatei geöffnet werden. Dazu schreiben wir uns zwei Prozeduren:
Einmal „OpenArchivFile“ (entspricht AssignFile), zum anderen „CloseArchivFile“ (entpricht CloseFile).
Hier also die OpenArchivFile-Routine:

procedure OpenArchivFile(ArchivName: String; var ArchivFile: ArchivTyp);
var I, q: Integer;
  Size: LongInt;
  AktPos: integer;
  s: string;
  SSize: byte; // Länge des Strings
begin
  ArchivFile.FileStart:=TStringList.Create;
  ArchivFile.FileNames:=TStringList.Create;

  if not FileExists(ArchivName) then Exit;

  AssignFile(ArchivFile.ArchivFile, ArchivName);
  ReSet(ArchivFile.ArchivFile,1);

  { Erste Datei }
  BlockRead(ArchivFile.ArchivFile, SSize, SizeOf(SSize));
  // zuerst wird ausgelesen, wie groß der Dateiname ist
  SetLength(s,SSize);
  // dann wird S diese Länge zugewiesen
  BlockRead(ArchivFile.ArchivFile,s[1],SSize);
  // anschließend kann der Dateiname aus der Archivdatei
  // ausgelesen werden.

  BlockRead(ArchivFile.ArchivFile,Size,SizeOf(Size));
  // die Größe der Datei

  ArchivFile.FileNames.Add(s);
  // der Dateiname
  ArchivFile.FileStart.Add(IntToStr(SSize+SizeOf(SSize)+SizeOf(Size)));
  // wo beginnen die Daten der ersten Datei?

  AktPos:=SSize+SizeOf(SSize)+SizeOf(Size)+size;
  // an welcher Stelle in der Archivdatei befinden wir uns gerade:
  // am Anfang der 2. Datei (+size)

  while AktPos+1<fileSize(ArchivFile.ArchivFile) do
  begin
    // jetzt machen wir solange das, was wir schon bei der ersten
    // Datei gemacht haben, bis wir am Ende der Datei angekommen
    // sind: zuerst die Größe des Dateinamens auslesen, dann den
    // Dateinamen und anschließend die Dateigröße auslesen.
    Seek(ArchivFile.ArchivFile,AktPos);
    BlockRead(ArchivFile.ArchivFile,SSize,SizeOf(SSize));
    SetLength(s,SSize);
    BlockRead(ArchivFile.ArchivFile,s[1],SSize);
    BlockRead(ArchivFile.ArchivFile,Size,SizeOf(Size));
    AktPos:=AktPos+SizeOf(SSize)+SSize+SizeOf(Size);
    Archivfile.FileNames.Add(s);
    ArchivFile.FileStart.Add(intToStr(AktPos));
    AktPos:=AktPos+Size; // wieder an den Anfang der nächsten Datei
  end;
end;

Und jetzt noch die CloseArchivFile-Prozedur:

procedure CloseArchivFile(var ArchivFile:ArchivTyp);
begin
  ArchivFile.FileStart.Free;
  ArchivFile.FileNames.Free;
  try
    CloseFile(ArchivFile.ArchivFile);
  except
  end;
end;