Delphi Rio 10.3.2:从 ZIP 文件中删除文件

Delphi Rio 10.3.2: remove file from a ZIP file

如何从 ZIP 文件中删除文件?到目前为止,我已经尝试了各种 libraries/components,none 成功了:

Delphi 的 TZip:不支持删除文件
KAzip:在 10.3
中不起作用 Jcl (jedi):关闭后损坏存档
缩写:在 10.3 中不起作用(损坏的文件)

有什么我可以使用完整源代码且没有外部 DLL 的东西吗? (除了使用 TZip 完全解压和重新打包)

最终制作了我自己的 proc(用于我自己的自定义库)。

tf = TFileStream with the zip
cSize = 压缩文件大小

只适合单个文件删除

procedure RemoveFile(name: string);
Var a,b: NativeInt;
   tm: TMemoryStream;
   RemovedSize,c: Cardinal;
const szChar = sizeof(AnsiChar);
begin

  // Locate File
  for a := Low(FileHeaders) to High(FileHeaders) do
   if CompareText(FileHeaders[a].fileName, name) = 0 then break;
  if a > High(FileHeaders) then Exit; // not found

  tm := TMemoryStream.Create;
  tf.Seek32(0, soBeginning);

  // copy up to the file to be removed
  tm.CopyFrom(tf, CentralDirs[a].headerOffset);

  // skip the file
  With FileHeaders[a] do
   RemovedSize := 30 + filenameLength + extraFieldLength + cSize;
  tf.Seek32(RemovedSize, soCurrent); // seek forward

  // update offsets for the next files
  for b := a+1 to High(FileHeaders) do
   Dec(CentralDirs[b].headerOffset, RemovedSize);

  // copy rest of the files
  c := 0;
  for b := a+1 to High(FileHeaders) do
  With FileHeaders[b] do
   Inc(c, 30 + filenameLength + extraFieldLength + cSize);

  tm.CopyFrom(tf, c);

  EOCD.centralDirOffset := tm.Position;

  // write Dir headers
  for c := Low(CentralDirs) to High(CentralDirs) do begin
    // skip removed file
    if c = a then Continue;
    With CentralDirs[c] do begin
      tm.Write(CentralDirs[c], 46);
      tm.Write(Pointer( CentralDirs[c].fileName )^,    szChar * CentralDirs[c].filenameLength);
      tm.Write(Pointer( CentralDirs[c].extraField )^,  szChar * CentralDirs[c].extraFieldLength);
      tm.Write(Pointer( CentralDirs[c].fileComment )^, szChar * CentralDirs[c].fileCommentLength);
    end;
  end;

  // Update EOCD data, copy
  With CentralDirs[a] do
   Dec(EOCD.centralDirSize, 46 + filenameLength + extraFieldLength + fileCommentLength);
  Dec(EOCD.numRecordsOnDisk);
  Dec(EOCD.numRecords);
  tm.Write(EOCD, 22);
  tm.Write(Pointer( EOCD.comment )^, szChar * EOCD.commentLength );
  tm.SaveToFile('test.zip');
  tm.Free;
end;