AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TZipFile

Ein Thema von Willie1 · begonnen am 3. Dez 2021 · letzter Beitrag vom 9. Dez 2021
Antwort Antwort
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.561 Beiträge
 
Delphi 12 Athens
 
#1

AW: TZipFile

  Alt 4. Dez 2021, 11:35
Die etwas Delphi-Implementation kann nur anhängen, aber nichts nachträglich ändern/überschreiben/löschen.

Du müsstest also die Datei kopieren, also lesend von einer ZIP, schreibend in eine Neue, und beim Kopieren deine Änderungen vornehmen.



Wenn die Dateigröße egal ist, dann einfach die Datei nochmal anhängen (mit dem gleichen Dateinamen) und beim entpacken überschreiben lassen, bzw. jeweils die letzte Version auslesen.
Ich hab es selber noch nicht ausprobiert, aber Delphi 11 soll nun auch Dateien aus dem Archiv entfernen können (delete):

https://docwiki.embarcadero.com/Libr...ZipFile.Delete
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: TZipFile

  Alt 4. Dez 2021, 23:09
Hallo, ich habe es selbst noch nicht ausprobiert aber bin auf diesen code gestossen, vielleicht funktioniert es für nicht-Delphi-11?
stackoverflow.com
Delphi-Quellcode:
type
  TZipFileHelper = class helper for TZipFile
    procedure Delete(FileName: string);
  end;

{ TZipFileHelper }

procedure TZipFileHelper.Delete(FileName: string);
var
  i, j: Integer;
  StartOffset, EndOffset, Size: UInt32;
  Header: TZipHeader;
  Buf: TBytes;
begin
  i := IndexOf(FileName);
  if i <> -1 then begin
    // Find extents for existing file in the file stream
    StartOffset := Self.FFiles[i].LocalHeaderOffset;
    EndOffset := Self.FEndFileData;
    for j := 0 to Self.FFiles.Count - 1 do begin
      if (Self.FFiles[j].LocalHeaderOffset > StartOffset) and
         (Self.FFiles[j].LocalHeaderOffset <= EndOffset) then
        EndOffset := Self.FFiles[j].LocalHeaderOffset;
    end;
    Size := EndOffset - StartOffset;
    // Update central directory header data
    Self.FFiles.Delete(i);
    for j := 0 to Self.FFiles.Count - 1 do begin
      Header := Self.FFiles[j];
      if Header.LocalHeaderOffset > StartOffset then begin
        Header.LocalHeaderOffset := Header.LocalHeaderOffset - Size;
        Self.FFiles[j] := Header;
      end;
    end;
    // Remove existing file stream
    SetLength(Buf, Self.FEndFileData - EndOffset);
    Self.FStream.Position := EndOffset;
    if Length(Buf) > 0 then
      Self.FStream.Read(Buf[0], Length(Buf));
    Self.FStream.Size := StartOffset;
    if Length(Buf) > 0 then
      Self.FStream.Write(Buf[0], Length(Buf));
    Self.FEndFileData := Self.FStream.Position;
  end;
end;
Aufruf:
Delphi-Quellcode:
ZipFile.Delete('document.txt');
ZipFile.Add(SS, 'document.txt');
Viel Erfolg!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Willie1

Registriert seit: 28. Mai 2008
709 Beiträge
 
Delphi 10.1 Berlin Starter
 
#3

AW: TZipFile

  Alt 5. Dez 2021, 17:25
Hallo KodeZwerg,
da hast du was Gutes bei Overflow gefunden. Ich werde es testen, bin aber sicher, dass es geht. Da habe ich schon oft Gutes gefunden.
Ich habe nur ein Problem: Bei dieser Methode wird wohl nur der Header gelöscht, die Datei bleibt. Mein von mir gegangener Weg wird bei Overflow genau so erwähnt. Bei 80 Dateien geht das sehr schnell und Speicherplatz auf der Festplatte ist kein Thema mehr.
Mein Ansatz ist richtig, könnt ihr erkennen, was an meinem Quelltext falsch ist. Sorry für meine Hartnäckigkeit.
Ich werde ein Archiv mit 80 Dateien mit dem Windows-Explorer packen und dann mit TZipFile und die Größe vergleichen.
Getan: Mit Windows: 87 KB mit TZipFile.Add: 90 KB. 75 Dateien mit jeweils 2777/2939 Bytes.

Willie.
Gut hören kann ich schlecht, schlecht sehen kann ich gut - Ersteres stimmt nicht, das zweite schon.

Geändert von Willie1 ( 5. Dez 2021 um 18:31 Uhr) Grund: TZipFile getestet
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.740 Beiträge
 
Delphi 6 Enterprise
 
#4

AW: TZipFile

  Alt 7. Dez 2021, 09:39
Hat nichts mit deinem Problem zu tun, aber wenn du die Funktion für nur eine Datei so abänderst, musst du das Problem anschließend nur in einer Funtion beheben, hast also nicht so viel doppelten Code.

Delphi-Quellcode:
procedure TWZZipFile.AddandOverride(const aFilename: string; const ArchiveFileName: string);
var s:TStringlist;
begin
  s:=TStringlist.create;
  s.Add(aFilename);
  AddandOverride(s, ArchiveFileName);
  s.Free;
end;
Zum Problem: Ich hab noch nicht mit TZipFile gearbeitet, aber kann das hinzufügen zum Archiv und direkt danach das löschen in einem Zug vielleicht das Problem sein:
Delphi-Quellcode:
  for i := Low(List) to High(List) do begin
        Add(List[i]);
        TFile.Delete(List[i]);
      end;
Machen nich die Ganzen Zip-Dinger auch eine Validierung? Geht das wenn die Datei schon gelöscht ist?
Ralph
  Mit Zitat antworten Zitat
Willie1

Registriert seit: 28. Mai 2008
709 Beiträge
 
Delphi 10.1 Berlin Starter
 
#5

AW: TZipFile

  Alt 8. Dez 2021, 18:43
Hat nichts mit deinem Problem zu tun, aber wenn du die Funktion für nur eine Datei so abänderst, musst du das Problem anschließend nur in einer Funtion beheben, hast also nicht so viel doppelten Code.

Delphi-Quellcode:
procedure TWZZipFile.AddandOverride(const aFilename: string; const ArchiveFileName: string);
var s:TStringlist;
begin
  s:=TStringlist.create;
  s.Add(aFilename);
  AddandOverride(s, ArchiveFileName);
  s.Free;
end;
Du hast recht.
Zitat:
Zum Problem: Ich hab noch nicht mit TZipFile gearbeitet, aber kann das hinzufügen zum Archiv und direkt danach das löschen in einem Zug vielleicht das Problem sein:
Delphi-Quellcode:
  for i := Low(List) to High(List) do begin
        Add(List[i]);
        TFile.Delete(List[i]);
      end;
Machen nich die Ganzen Zip-Dinger auch eine Validierung? Geht das wenn die Datei schon gelöscht ist?
Die Zip-Datei wird neu geschrieben, sie wird nur immer größer. Wi.
Gut hören kann ich schlecht, schlecht sehen kann ich gut - Ersteres stimmt nicht, das zweite schon.
  Mit Zitat antworten Zitat
Willie1

Registriert seit: 28. Mai 2008
709 Beiträge
 
Delphi 10.1 Berlin Starter
 
#6

AW: TZipFile

  Alt 9. Dez 2021, 17:03
Hallo,
ich hab' den Fehler gefunden!
Delphi-Quellcode:
      Open(TempName, zmWrite); //hier liegt der Fehler
      for i := Low(List) to High(List) do begin
        Add(List[i]);// <-----------------
        TFile.Delete(List[i]);
      end;
      Close;
ich benutze die Instanz TZipFile zweimal, einmal zum Auspacken des alten Zip und einmal zum Schreiben des neuen Zip. Ich war davon aus gegangen, dass mit Open Close ausgelöst wird (so steht es in der Hilfe) und das alte Archiv geschlossen wird. Das ist aber nicht so. Die alten Dateien werden nicht mehr "verlinkt", stehen aber noch im neuen Archiv. Deshalb wird es immer größer. So ist es mir zunächst nicht aufgefallen, weil es funktioniert.
Delphi-Quellcode:
  if Done then begin
      ZipFi := TZipFile.Create;// <--- Neu
      List := TDirectory.GetFiles(TempPa);
      TempName := ExtractFilePath(ArchiveFilename) + ExtractFilename(TPath.GetTempFileName);
      ZipFi.Open(TempName, zmWrite);
      for i := Low(List) to High(List) do begin
        ZipFi.Add(List[i]);
        TFile.Delete(List[i]);
      end;
      ZipFi.Free;
    end;
So ist es richtig.
Es stellt sich mir die Frage: liegt das an meinen Programmierkünsten oder haben die "Delphi-Bauer" etwas übersehen?
Gruß Willie,

Hoffentlich seit ihr hier noch dabei.
Gut hören kann ich schlecht, schlecht sehen kann ich gut - Ersteres stimmt nicht, das zweite schon.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: TZipFile

  Alt 9. Dez 2021, 17:10
Hallo Willie, wenn ich die Zeit finde werde ich "meine" methode mal ausprobieren, da ich ein "komplett entzippen nur um eine datei auszutauschen" als sehr ineffizient finde.
Bei miniatur zips mag es nicht weiter ins gewicht fallen, bei größen schon (plus hardware verschleiß bei mechanischen festplatten!)

Ich habe allerdings auch irgendwo gelesen das TZipFile wohl keine Helper mehr zulässt.... alles noch ungetestet.

Grüße
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:52 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