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;
如何从 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;