![]() |
Datei Archiv
Hallo!
jeder kennt es - vorallem von spielen. Diese übergroßen Ressourcen Dateien in denen alles drin ist :) naja, ich möchte au so was probieren. Hab auch schon meine Anfänge. Aber komm leider nicht weiter. Hier ist meine Klasse mit der ich das Realisieren möchte. Aber es Funktioniert leider nicht so. Ich hab auch keine Ahnung wie ich folgende Sachen realisieren soll. + Unterordner + Datei Suchen Wie ihr seht hab ich es noch nichtmal geschafft die wirkliche Datei ins Archiv zu bekommen. Bitte, helft mir! (ich weiß nicht mal ob ich im richtigen Forum bin - eigtl. gehört das ja eher unter Datenbank aber das kann man ja sehen wie man will =) ) Danke, Daniel
Delphi-Quellcode:
...
Const BufferSize = 32; type TArchivFile = Record FileName : String[100]; FileSize : integer; FileContent : File; Inserted : TDateTime; Modified : TDateTime; Status : smallint; Visible : Boolean; end; type TZPAKArchiv = class private TArchiv : File of TArchivFile; function GetCount: Integer; public Constructor Create; procedure OpenArchiv(filename : String); procedure CloseArchiv; procedure DeleteFile(Position : LongWord); function ReadFile(Position : LongWord) : TArchivFile; procedure AddFile(ArchivFile : TArchivFile); procedure ModFile(ArchivFile : TArchivFile; Position : LongWord); property Count : Integer Read GetCount; end; implementation { TZPAKArchiv } constructor TZPAKArchiv.Create; begin inherited; end; procedure TZPAKArchiv.CloseArchiv; begin CloseFile(TArchiv); end; procedure TZPAKArchiv.OpenArchiv(filename : String); begin AssignFile(TArchiv, filename); if FileExists(filename) then ReSet(TArchiv) else ReWrite(TArchiv); end; function TZPAKArchiv.ReadFile(Position: LongWord): TArchivFile; begin if (Position < 0) or (Position >= FileSize(TArchiv)) then Exit else begin Seek(TArchiv, Position); read(TArchiv, Result); end; end; procedure TZPAKArchiv.DeleteFile(Position: LongWord); var Buffer : array[0..BufferSize - 1] of TArchivFile; i, p : Integer; StartRecord, EndRecord : Integer; Max : Integer; begin Seek(TArchiv, Position-1); StartRecord := Position+1; EndRecord := Position; While StartRecord < EndRecord do begin Max := BufferSize; if Max > EndRecord - StartRecord then Max := EndRecord - StartRecord; Seek(TArchiv, StartRecord); for i := 0 to Max -1 do Read(TArchiv, Buffer[i]); Seek(TArchiv, StartRecord-1); for i := 0 to Max - 1 do Write(TArchiv, Buffer[i]); inc(StartRecord); end; Truncate(TArchiv); end; procedure TZPAKArchiv.AddFile(ArchivFile: TArchivFile); var Buffer : Array[0..BufferSize - 1] of TArchivFile; i, p : integer; begin Seek(TArchiv,0); p := 0; while not eof(TArchiv) do begin Read(TArchiv, Buffer[p]); inc(p); end; closeFile(TArchiv); Buffer[p+1].FileName := ArchivFile.FileName; Buffer[p+1].FileSize := ArchivFile.FileSize; // Buffer[p+1].FileContent := ArchivFile.FileContent; Buffer[p+1].Inserted := ArchivFile.Inserted; Buffer[p+1].Modified := ArchivFile.Modified; Buffer[p+1].Status := ArchivFile.Status; Buffer[p+1].Visible := ArchivFile.Visible; ReWrite(TArchiv); for i := 0 to p do Write(TArchiv, Buffer[i]); end; procedure TZPAKArchiv.ModFile(ArchivFile: TArchivFile; Position: LongWord); var Datensatz : TARchivFile; begin Seek(TArchiv, Position-1); Datensatz.FileName := ARchivFile.FileName; Datensatz.FileSize := ArchivFile.FileSize; // Datensatz.FileContent := ArchivFile.FileContent; Datensatz.Inserted := Archivfile.Inserted; Datensatz.Modified := Archivfile.Modified; Datensatz.Status := ArchivFile.Status; Datensatz.Visible := ArchivFile.Visible; write(TArchiv, Datensatz); end; function TZPAKArchiv.GetCount: Integer; begin Result := FileSize(TArchiv)-1; end; ... |
Re: Datei Archiv
Also, die Eckdaten der Datei kannst du ja so am Anfang des Archivs speichern. Den Inhalt der Datei ebenfalls im Record zu speichern wäre zwar nicht unmöglich, aber nich sehr günstig. Ich würde statt
Delphi-Quellcode:
FileContent : File;
Delphi-Quellcode:
verwenden und die Inhalte der Dateien per TFileStream (siehe OH) nach den records in das Archiv schreiben. FileContentOffset ist dann die Position der Daten der jeweiligen Datei im Archiv. Du kannst diese dann z.B. mit
FileContentOffset : Cardinal;
Delphi-Quellcode:
einlesen.
var
fs : TFileStream; fsData : TFileStream; //.. begin fs := TFileStream.Create('C:\meine.pak', fmOpenRead); fsData := TFileStream.Create(Datensatz.FileName, fmOpenReadWrite); try fs.Seek(Datensatz.FileContentOffset, soFromBeginning); fsData.CopyFrom(fs, Datensatz.FileSize); finally fsData.Free; end; end; |
Re: Datei Archiv
hmm... versteh was du meinst. Aber ich weiß leider nicht wie ich das machen soll.
Woher bekomme ich den Offset bzw. wie kann ich ihn setzen? Danke! |
Re: Datei Archiv
Liste der Anhänge anzeigen (Anzahl: 1)
Habe mal ein kleines Beispiel geschrieben, ist nicht perfekt aber zeigt, wie meine Idee umsetzbar wäre.
|
Re: Datei Archiv
Ich Schaus mir mal an Danke!
|
Re: Datei Archiv
Hab grad noch was geändert, weil ne Kompo drin war, die du evtl. nicht drin hast.
|
Re: Datei Archiv
Super! genau so etwas hab ich gebraucht.
Jetzt noch meine Frage: Wie mache ich das mit den unterordnern? Vorschläge, Ideen? suchen dürfte ja relativ einfach gehen denk ich. Nochmals danke! |
Re: Datei Archiv
Also, um den Pfad mit zu speichern brauchst du ja nur das Laufwerk wegschneiden.
Aus D:\Pfad\nocheiner\eine.dat wird dann Pfad\nocheiner\eine.dat Dann musst du nur noch später beim entpacken eine Prozedur erstellen, die nach und nach die unter ordner erstellt:
Delphi-Quellcode:
Nicht getestet.
procedure MkSubDirs(DestDir : String; AFile : String);
var AFileName : String; CurDir : String; //.. begin AFileName := AFile; CurDir := DestDir; while (Pos('\', AFilename) > 0) do begin CurDir := CurDir + Copy(AFilename, 1, Pos('\', AFilename)-1); Delete(AFilename, 1, Pos('\', AFilename)); If not DirectoryExists(CurDir) then MkDir(CurDir); CurDir := CurDir + '\'; end; end; |
Re: Datei Archiv
Danke!
hast mir sehr geholfen. Bastel gerade eine Klasse und eine Komponente zusammen. hab noch ein paar Fragen: - Kann ich den Header "einfach" so erweitern... alt:
Delphi-Quellcode:
neu:
TFileArchiveHeader = Record
FileTag : array[0..3] Of Char; Count : Cardinal; end;
Delphi-Quellcode:
... oder muss ich da in der Load und Save Funktion änderungen machen?
TFileArchiveHeader = Record
FileTag : array[0..3] Of Char; Password : String[25]; Password : WordBool; Count : Cardinal; end; soweit ich weiß muss bei Strings ja eine Begrenzung sein (in diesem fall 25) 1. Stimmt das und 2. muss das Passwort dann 25 Zeichen lang sein oder dürfen es weniger sein. - Ich würde gerne besser damit arbeiten können. damit meine ich: ich möchte in ein vorhandenes Package Dateien einfügen, bzw. Welche löschen. Oder sogar ändern. [ Change ] hab grad gesehen dass du eine neue Version geuppt hast. Da ist das mit dem anfügen ja drin... [/ Change] - Vielleicht noch einen Schritt weiter: Wäre es möglich (ja möglich bestimmt ich weiß :-) - bloß wie *G*) wenn man Größere Dateien einbindet einen Progressbalken fortschreiten zu lassen? Ich habe mir für die Ordner das so gedacht. Also dass für die Ordner ein neuer Wert im Record angelegt wird bsp: Datei-1 filename : 'Testdatei1'; folder : '\Folder1\SubFolder1'; Datei-2 filename : 'Testdatei2'; folder : '\Folder1\'SubFolder2'; Dann kann ich in meine Abgeleiteten TListView komponente schön die einzelnen Ordner anzeigen. Mit nem Filter oder so. Muss i mir no was einfallen lassen. So... genug Text so spät -ehhh Früh am Morgen *G* Danke für die Aufmerksamkeit Daniel |
Re: Datei Archiv
Liste der Anhänge anzeigen (Anzahl: 1)
So, besser spät als nie - hab da vor einiger zeit schonmal sowas gebastelt - musst du nur noch anpassen wegen deinem ladebalken - also einfach ne callbackfunktion reinbasteln und fertsch. Alternativ könntest du das ganze auch in ner simplen zipdatei organisieren. In der Zipdatei gibts noch einen ordner "komponenten" oder so. In dem sind noch 3 komponenten die für das demo benötigt werden sowie die filepack-komponente. Einfach die pas datein einem package hinzufügen und nicht vergessen die "*.dcr" datein aus dem package zu löschen sonst kommts zu dem fehler duplicate resources oder so
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:56 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 by Thomas Breitkreuz