加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi XE2 TZipFile:替换zip存档中的文件

发布时间:2020-12-15 04:01:43 所属栏目:大数据 来源:网络整理
导读:我想用Delphi XE2 / XE3标准System.Zip单元替换zip存档中的文件(= delete old和add new).但是没有替换/删除方法.有没有人知道如何在不需要提取所有文件并将其添加到新存档的情况下实现它? 我有这个代码,但如果它已经存在,它会再次添加“document.txt”: va
我想用Delphi XE2 / XE3标准System.Zip单元替换zip存档中的文件(= delete old和add new).但是没有替换/删除方法.有没有人知道如何在不需要提取所有文件并将其添加到新存档的情况下实现它?

我有这个代码,但如果它已经存在,它会再次添加“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;

注意:我之前使用过TPAbbrevia(完成了这项工作),但我现在想使用Delphi的Zip单元.所以请不要回答“使用其他图书馆”之类的内容.谢谢.

解决方法

我推荐Abbrevia因为我有偏见:),你已经知道了,它不需要任何黑客攻击.除此之外,这是你的黑客:
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');

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读