Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Eigenes Archivformat (https://www.delphipraxis.net/111264-eigenes-archivformat.html)

Nils_13 1. Apr 2008 12:27


Eigenes Archivformat
 
Hi,

ich brauche ein eigenes Archivformat. Es soll nichts weiter als Bilder und eventuell noch eine Index-Datei (zur leichteren Weiterverarbeitung des Inhalts) rein. Es soll nämlich ein Skinformat werden. Ich möchte nicht ZIP- oder RAR-Dateien haben (gefällt mir einfach nicht) und genausowenig Ordner. Es soll einfach nur eine Datei sein, die die anderen ohne Kompression oder sonstiges enthält. Wie könnte man so etwas programmieren. Abgesehen vom kleinen Skinsystem interessiert mich das auch so.

arbu man 1. Apr 2008 12:33

Re: Eigenes Archivformat
 
Ein Stream reicht völlig aus, Zuerst schreibst du 255 Zeichen für den Dateinamen in den Stream dann einen int für die Länge der Daten und dann die Daten der Datei. Beim auslesen kannst du dir dann eine Liste der Dateinamen erstellen und dann die Dateiinhalte auslesen. Ich hoffe du hast das Prinzip verstanden. Luckie hat soetwas glaub ich mit seinen SFX-Tools realisiert.

franktron 1. Apr 2008 12:49

Re: Eigenes Archivformat
 
Schau mal in der Codelib da hab ich mal sowas gemacht

Nils_13 1. Apr 2008 17:27

Re: Eigenes Archivformat
 
@arbu: Müssen es wirklich 255 Zeichen für den Dateinamen sein -> Müssen die Zeichen falls nicht erfüllt auf 255 mit irgendetwas aufgefüllt werden ?
@franktron: In der Codebibliothek finde ich von dir nur einen Beitrag und auch allgemein keinen Eintrag für meinen Fall.

phreax 1. Apr 2008 17:39

Re: Eigenes Archivformat
 
Guckst Du hier: myArchiv Tutorial

HTH phreax

Die Muhkuh 1. Apr 2008 17:43

Re: Eigenes Archivformat
 
Du kannst auch erst einen int abspeichern, der die Länge des Namens angibt, danach den Namen auslesen, dann wieder ein int (oder was größeres) für die Länge der Datei und zu letzt nun die Datei.

Nils_13 1. Apr 2008 20:49

Re: Eigenes Archivformat
 
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.

arbu man 1. Apr 2008 21:08

Re: Eigenes Archivformat
 
Zitat:

Zitat von Nils_13
Müssen es wirklich 255 Zeichen für den Dateinamen sein -> Müssen die Zeichen falls nicht erfüllt auf 255 mit irgendetwas aufgefüllt werden ?

Nein müssen es natürlich nicht, das sollte nur verdeutlichen das man statische Datentypen speichern kann. Ein auffüllen kann man bei Dateinamen einfach durch ein * machen (das es im Dateinamen nicht vorkommen kann, nacher mit StringReplace o.ä. entfernen). Als stischer Datentype würde sich aber der Shortstring anbieten (der ist ja maximal 255 Zeichen lang). Im Speicher wird er in einer Art record organisiert:
Delphi-Quellcode:
record
  Data: array[0..255] of Char;
  Length: Byte;
end;
Du siehst man könnte auch Füllzeichen verwenden (für den Anwendungsfall)

Wie du es realisierst bleibt natürlich dir überlassen, ein Stream bietet dir wirklich alle Möglichkeiten...

mfg, Björn

taaktaak 1. Apr 2008 21:15

Re: Eigenes Archivformat
 
@Nils:

Bin zwar ein alter BlockRead-Fan, trotzdem komme ich langsam aber sicher zu der Erkenntnis, dass Streams moderner und "einfach besser" sind. Wieso finde ich jetzt bei dir diese "altmodischen Konstrukte"? Gibt's da 'ne Erklärung?

bitsetter 1. Apr 2008 21:27

Re: Eigenes Archivformat
 
@taaktaak

Bestimmt weil ihm das vorgeschlagen wurde.
Zitat:

Zitat von phreax
Guckst Du hier: myArchiv Tutorial

HTH phreax



Alle Zeitangaben in WEZ +1. Es ist jetzt 08:45 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz