gpt4 book ai didi

德尔福 XE2 TZipFile : replace a file in zip archive

转载 作者:行者123 更新时间:2023-12-03 14:46:54 27 4
gpt4 key购买 nike

我想用 Delphi XE2/XE3 标准 System.Zip 单元替换 zip 存档中的文件(= 删除旧文件并添加新文件)。但没有替换/删除方法。有谁知道如何在不需要提取所有文件并将它们添加到新存档中的情况下实现它?

我有这段代码,但如果“document.txt”已经存在,它会再次添加它:

var
ZipFile: TZipFile;
SS: TStringStream;
const
ZipDocument = 'E:\document.zip';
begin
ZipFile := TZipFile.Create; //Zipfile: TZipFile
SS := TStringStream.Create('hello');
try
if FileExists(ZipDocument) then
ZipFile.Open(ZipDocument, zmReadWrite)
else
ZipFile.Open(ZipDocument, zmWrite);

ZipFile.Add(SS, 'document.txt');

ZipFile.Close;
finally
SS.Free;
ZipFile.Free;
end;
end;

注意:我之前使用过 TPAbrevia(它完成了这项工作),但我现在想使用 Delphi 的 Zip 单元。所以请不要回答“使用另一个库”之类的问题。谢谢。

最佳答案

我推荐 Abbrvia,因为我有偏见:),你已经知道它了,而且它不需要任何技巧。除此之外,这是你的技巧:

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;

用法:

ZipFile.Delete('document.txt');
ZipFile.Add(SS, 'document.txt');

关于德尔福 XE2 TZipFile : replace a file in zip archive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13164299/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com