📄 kazip.pas
字号:
Begin
FParent.FZipStream.Position := Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
SetLength(BUF,Items[X].LocalEntrySize);
FParent.FZipStream.Read(BUF[1],Length(BUF));
FParent.FZipStream.Position := TargetPos;
Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader := TargetPos;
FParent.FZipStream.Write(BUF[1],Length(BUF));
TargetPos := FParent.FZipStream.Position;
End;
End;
FParent.FZipStream.Position := TargetPos;
//************************************ MARK START OF CENTRAL DIRECTORY
FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory := FParent.FZipStream.Position;
//************************************ SAVE CENTRAL DIRECTORY
For X := 0 To Count-1 do
Begin
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile,SizeOf(Self.Items[X].FCentralDirectoryFile)-3*SizeOf(String));
if Self.Items[X].FCentralDirectoryFile.FilenameLength > 0 Then
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileName[1],Self.Items[X].FCentralDirectoryFile.FilenameLength);
if Self.Items[X].FCentralDirectoryFile.ExtraFieldLength > 0 Then
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.ExtraField[1],Self.Items[X].FCentralDirectoryFile.ExtraFieldLength);
if Self.Items[X].FCentralDirectoryFile.FileCommentLength > 0 Then
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileComment[1],Self.Items[X].FCentralDirectoryFile.FileCommentLength);
End;
//************************************ SAVE END CENTRAL DIRECTORY RECORD
FParent.FEndOfCentralDirPos := FParent.FZipStream.Position;
FParent.FEndOfCentralDir.SizeOfTheCentralDirectory := FParent.FEndOfCentralDirPos-FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
Dec(FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
Dec(FParent.FEndOfCentralDir.TotalNumberOfEntries);
FParent.FZipStream.Write(FParent.FEndOfCentralDir, SizeOf(TEndOfCentralDir));
//************************************ SAVE ZIP COMMENT IF ANY
FParent.FZipCommentPos := FParent.FZipStream.Position;
if Length(ZipComment) > 0 Then
Begin
FParent.FZipStream.Write(ZipComment[1],Length(ZipComment));
End;
FParent.FZipStream.Size := FParent.FZipStream.Position;
End
Else
Begin
TempFileName := FParent.GetDelphiTempFileName;
TempStream := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
Try
FParent.SaveToStream(TempStream);
TempStream.Position := 0;
OSL := FParent.FZipStream.Size;
Try
FParent.FZipStream.Size := TempStream.Size;
Except
FParent.FZipStream.Size := OSL;
Raise;
End;
FParent.FZipStream.Position := 0;
FParent.FZipStream.CopyFrom(TempStream,TempStream.Size);
//*********************************************************************
FParent.FZipHeader.ParseZip(FParent.FZipStream);
//*********************************************************************
Finally
TempStream.Free;
DeleteFile(TempFileName)
End;
End;
if NOT FParent.FBatchMode Then
Begin
FParent.DoChange(FParent,3);
End;
end;
procedure TKAZipEntries.Remove(Item: TKAZipEntriesEntry);
Var
X : Integer;
begin
For X := 0 To Count-1 do
Begin
if Self.Items[X]=Item Then
Begin
Remove(X);
Exit;
End;
End;
end;
procedure TKAZipEntries.Remove(FileName: String);
Var
I : Integer;
begin
I := IndexOf(FileName);
if I <> -1 Then Remove(I);
end;
Procedure TKAZipEntries.RemoveSelected;
Var
X : Integer;
Begin
For X := Count-1 Downto 0 do
Begin
if Self.Items[X].Selected Then
Begin
Remove(X);
End;
End;
End;
Function TKAZipEntries.IndexOf(Const FileName:String):Integer;
Var
X : Integer;
FN : String;
Begin
Result := -1;
FN := ToZipName(FileName);
For X := 0 To Count-1 do
Begin
if AnsiCompareText(FN,ToZipName(Items[X].FCentralDirectoryFile.FileName))=0 Then
Begin
Result := X;
Exit;
End;
End;
End;
Function TKAZipEntries.AddStreamFast( ItemName : String;
FileAttr : Word;
FileDate : TDateTime;
Stream : TStream):TKAZipEntriesEntry;
Var
Compressor : TCompressionStream;
CS : TStringStream;
CM : WORD;
S : String;
X : Integer;
I : Integer;
UL : Integer;
CL : Integer;
FCRC32 : Cardinal;
SizeToAppend : Integer;
ZipComment : String;
Level : TCompressionLevel;
begin
//*********************************** COMPRESS DATA
ZipComment := FParent.Comment.Text;
if NOT FParent.FStoreRelativePath Then
ItemName := ExtractFileName(ItemName);
ItemName := ToZipName(ItemName);
I := IndexOf(ItemName);
if I > -1 Then Remove(I);
CS := TStringStream.Create('');
CS.Position := 0;
Try
UL := Stream.Size-Stream.Position;
SetLength(S,UL);
CM := 0;
if UL > 0 Then
Begin
Stream.Read(S[1],UL);
CM := 8;
End;
FCRC32 := CalcCRC32(S);
FParent.FCurrentDFS := UL;
Level := clDefault;
Case FParent.FZipCompressionType of
ctNormal : Level := clDefault;
ctMaximum : Level := clMax;
ctFast : Level := clFastest;
ctSuperFast : Level := clFastest;
ctNone : Level := clNone;
End;
if CM = 8 Then
Begin
Compressor := TCompressionStream.Create(Level,CS);
Try
Compressor.OnProgress := FParent.OnCompress;
Compressor.Write(S[1],UL);
Finally
Compressor.Free;
End;
S := Copy(CS.DataString, 3, Length(CS.DataString)-6);
End;
Finally
CS.Free;
End;
//***********************************
CL := Length(S);
//*********************************** FILL RECORDS
Result := TKAZipEntriesEntry(Self.Add);
With Result.FLocalFile do
Begin
LocalFileHeaderSignature := $04034B50;
VersionNeededToExtract := 20;
GeneralPurposeBitFlag := 0;
CompressionMethod := CM;
LastModFileTimeDate := DateTimeToFileDate(FileDate);
Crc32 := FCRC32;
CompressedSize := CL;
UncompressedSize := UL;
FilenameLength := Length(ItemName);
ExtraFieldLength := 0;
FileName := ItemName;
ExtraField := '';
CompressedData := '';
End;
With Result.FCentralDirectoryFile Do
Begin
CentralFileHeaderSignature := $02014B50;
VersionMadeBy := 20;
VersionNeededToExtract := 20;
GeneralPurposeBitFlag := 0;
CompressionMethod := CM;
LastModFileTimeDate := DateTimeToFileDate(FileDate);
Crc32 := FCRC32;
CompressedSize := CL;
UncompressedSize := UL;
FilenameLength := Length(ItemName);
ExtraFieldLength := 0;
FileCommentLength := 0;
DiskNumberStart := 0;
InternalFileAttributes := 0;
ExternalFileAttributes := FileAttr;
RelativeOffsetOfLocalHeader := FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
FileName := ItemName;
ExtraField := '';
FileComment := '';
End;
//************************************ EXPAND ZIP STREAM SIZE
SizeToAppend := 0;
SizeToAppend := SizeToAppend+SizeOf(Result.FLocalFile)-3*SizeOf(String);
SizeToAppend := SizeToAppend+Result.FLocalFile.FilenameLength;
SizeToAppend := SizeToAppend+CL;
SizeToAppend := SizeToAppend+SizeOf(Result.FCentralDirectoryFile)-3*SizeOf(String);
SizeToAppend := SizeToAppend+Result.FCentralDirectoryFile.FilenameLength;
FParent.FZipStream.Size := FParent.FZipStream.Size+SizeToAppend;
//************************************ SAVE LOCAL HEADER AND COMPRESSED DATA
FParent.FZipStream.Position := Result.FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
FParent.FZipStream.Write(Result.FLocalFile,SizeOf(Result.FLocalFile)-3*SizeOf(String));
if Result.FLocalFile.FilenameLength > 0 Then FParent.FZipStream.Write(Result.FLocalFile.FileName[1],Result.FLocalFile.FilenameLength);
if CL > 0 Then FParent.FZipStream.Write(S[1],CL);
//************************************ MARK START OF CENTRAL DIRECTORY
FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory := FParent.FZipStream.Position;
//************************************ SAVE CENTRAL DIRECTORY
For X := 0 To Count-1 do
Begin
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile,SizeOf(Self.Items[X].FCentralDirectoryFile)-3*SizeOf(String));
if Self.Items[X].FCentralDirectoryFile.FilenameLength > 0 Then
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileName[1],Self.Items[X].FCentralDirectoryFile.FilenameLength);
if Self.Items[X].FCentralDirectoryFile.ExtraFieldLength > 0 Then
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.ExtraField[1],Self.Items[X].FCentralDirectoryFile.ExtraFieldLength);
if Self.Items[X].FCentralDirectoryFile.FileCommentLength > 0 Then
FParent.FZipStream.Write(Self.Items[X].FCentralDirectoryFile.FileComment[1],Self.Items[X].FCentralDirectoryFile.FileCommentLength);
End;
//************************************ SAVE END CENTRAL DIRECTORY RECORD
FParent.FEndOfCentralDirPos := FParent.FZipStream.Position;
FParent.FEndOfCentralDir.SizeOfTheCentralDirectory := FParent.FEndOfCentralDirPos-FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
Inc(FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk);
Inc(FParent.FEndOfCentralDir.TotalNumberOfEntries);
FParent.FZipStream.Write(FParent.FEndOfCentralDir, SizeOf(TEndOfCentralDir));
//************************************ SAVE ZIP COMMENT IF ANY
FParent.FZipCommentPos := FParent.FZipStream.Position;
if Length(ZipComment) > 0 Then
Begin
FParent.FZipStream.Write(ZipComment[1],Length(ZipComment));
End;
Result.FDate := FileDate;
if (Result.FCentralDirectoryFile.GeneralPurposeBitFlag And 1) > 0 Then
Result.FIsEncrypted := True
Else
Result.FIsEncrypted := False;
Result.FIsFolder := (Result.FCentralDirectoryFile.ExternalFileAttributes and faDirectory) > 0;
Result.FCompressionType := ctUnknown;
if (Result.FCentralDirectoryFile.CompressionMethod=8) or (Result.FCentralDirectoryFile.CompressionMethod=9) Then
Begin
Case Result.FCentralDirectoryFile.GeneralPurposeBitFlag AND 6 of
0 : Result.FCompressionType := ctNormal;
2 : Result.FCompressionType := ctMaximum;
4 : Result.FCompressionType := ctFast;
6 : Result.FCompressionType := ctSuperFast
End;
End;
if NOT FParent.FBatchMode Then
Begin
FParent.DoChange(FParent,2);
End;
end;
Function TKAZipEntries.AddStreamRebuild( ItemName : String;
FileAttr : Word;
FileDate : TDateTime;
Stream : TStream):TKAZipEntriesEntry;
Var
Compressor : TCompressionStream;
CS : TStringStream;
CM : Word;
S : String;
UL : Integer;
CL : Integer;
I : Integer;
FCRC32 : Cardinal;
OSL : Cardinal;
ZipComment : String;
TempStream : TFileStream;
TempFileName : String;
Level : TCompressionLevel;
Begin
TempFileName := FParent.GetDelphiTempFileName;
TempStream := TFileStream.Create(TempFileName,fmOpenReadWrite or FmCreate);
Try
//*********************************** SAVE ALL OLD LOCAL ITEMS
FParent.RebuildLocalFiles(TempStream);
//*********************************** COMPRESS DATA
ZipComment := FParent.Comment.Text;
if NOT FParent.FStoreRelativePath Then
ItemName := ExtractFileName(ItemName);
ItemName := ToZipName(ItemName);
I := IndexOf(ItemName);
if I > -1 Then Remove(I);
CM := 0;
CS := TStringStream.Create('');
CS.Position := 0;
Try
UL := Stream.Size-Stream.Position;
SetLength(S,UL);
if UL > 0 Then
Begin
Stream.Read(S[1],UL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -