⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kazip.pas

📁 Complete Zip Program
💻 PAS
📖 第 1 页 / 共 5 页
字号:
                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 + -