📄 jvqzlibmultiple.pas
字号:
ZStream := TJclZLibCompressStream.Create(Stream);
try
if Assigned(FOnCompressingFile) then
FOnCompressingFile(Self, FilePath);
{ (RB) ZStream has an OnProgress event, thus CopyFrom can be used }
repeat
Count := FileStream.Read(Buffer, SizeOf(Buffer));
ZStream.Write(Buffer, Count);
DoProgress(FileStream.Position, FileStream.Size);
until Count = 0;
finally
ZStream.Free;
end;
if Assigned(FOnCompressedFile) then
FOnCompressedFile(Self, FilePath);
if StorePaths then
WriteFileRecord(Directory, FileName, FileStream.Size, Stream.Size)
else
WriteFileRecord('', FileName, FileStream.Size, Stream.Size);
DestStream.CopyFrom(Stream, 0);
finally
FileStream.Free;
Stream.Free;
end;
end;
procedure TJvZlibMultiple.CompressDirectory(Directory: string;
Recursive: Boolean; FileName: string);
var
TmpStream: TStream;
begin
// don't create file until we save it so we don't accidentally
// try to compress ourselves!
DeleteFile(FileName); // make sure we don't compress a previous archive into ourselves
TmpStream := CompressDirectory(Directory, Recursive);
try
TMemoryStream(TmpStream).SaveToFile(FileName);
finally
TmpStream.Free;
end;
end;
function TJvZlibMultiple.CompressFiles(Files: TStrings): TStream;
var
I: Integer;
S1, S2, Common: string;
begin
{ (RB) Letting this function create a stream is not a good idea;
see other CompressFiles function that causes a memory leak }
Result := TMemoryStream.Create;
if Files.Count = 0 then
Exit;
//Find the biggest Common part of all files
S1 := UpperCase(Files[0]);
for I := 1 to Files.Count - 1 do
begin
S2 := Files[I];
while (Pos(S1, S2) = 0) and (S1 <> '') do
S1 := Copy(S1, 1, Length(S1) - 1);
end;
{ (RB) This should be Common := S1 (?) }
Common := S2;
//Add the files to the stream
for I := 0 to Files.Count - 1 do
begin
S1 := ExtractFileName(Files[I]);
S2 := ExtractFilePath(Files[I]);
S2 := Copy(S2, 1, Length(Common));
AddFile(S1, S2, Files[I], Result);
end;
Result.Position := 0;
end;
procedure TJvZlibMultiple.CompressFiles(Files: TStrings; FileName: string);
var
TmpStream: TStream;
begin
TmpStream := CompressFiles(Files);
try
TMemoryStream(TmpStream).SaveToFile(FileName);
finally
TmpStream.Free;
end;
if Assigned(FOnCompletedAction) then
FOnCompletedAction(Self);
end;
procedure TJvZlibMultiple.DecompressStream(Stream: TStream;
Directory: string; Overwrite: Boolean; const RelativePaths: Boolean);
var
FileStream: TFileStream;
ZStream: TJclZLibDecompressStream;
CStream: TMemoryStream;
B, LastPos: Byte;
S: string;
Count, FileSize, I: Integer;
Buffer: array [0..1023] of Byte;
TotalByteCount: Longword;
WriteMe: Boolean; // Allow skipping of files instead of writing them.
begin
if Directory <> '' then
Directory := IncludeTrailingPathDelimiter(Directory);
while Stream.Position < Stream.Size do
begin
//Read and force the directory
Stream.Read(B, SizeOf(B));
SetLength(S, B);
if B > 0 then
Stream.Read(S[1], B);
ForceDirectories(Directory + S);
if S <> '' then
S := IncludeTrailingPathDelimiter(S);
//This make files decompress either on Directory or Directory+SavedRelativePath
if not RelativePaths then
S := '';
//Read filename
Stream.Read(B, SizeOf(B));
if B > 0 then
begin
LastPos := Length(S);
SetLength(S, LastPos + B);
Stream.Read(S[LastPos + 1], B);
end;
Stream.Read(FileSize, SizeOf(FileSize));
Stream.Read(I, SizeOf(I));
CStream := TMemoryStream.Create;
try
CStream.CopyFrom(Stream, I);
CStream.Position := 0;
//Decompress the file
S := Directory + S;
if Overwrite or not FileExists(S) then
begin
//This fails if Directory isn't empty
WriteMe := True;
if Assigned(FOnDecompressingFile) then
FOnDecompressingFile(Self, S, WriteMe);
if WriteMe then
FileStream := TFileStream.Create(S, fmCreate or fmShareExclusive)
else
FileStream := nil; // skip it!
ZStream := TJclZLibDecompressStream.Create(CStream);
try
TotalByteCount := 0;
{ (RB) ZStream has an OnProgress event, thus copyfrom can be used }
repeat
Count := ZStream.Read(Buffer, SizeOf(Buffer));
if Assigned(FileStream) then
begin
FileStream.Write(Buffer, Count);
DoProgress(FileStream.Size, FileSize);
end;
Inc(TotalByteCount, Count);
until Count = 0;
if Assigned(FOnDecompressedFile) then
FOnDecompressedFile(Self, S, TotalByteCount);
finally
FreeAndNil(FileStream);
ZStream.Free;
end;
end;
finally
CStream.Free;
end;
end;
end;
procedure TJvZlibMultiple.DecompressFile(FileName, Directory: string;
Overwrite: Boolean; const RelativePaths: Boolean);
var
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
try
Stream.Position := 0;
DecompressStream(Stream, Directory, Overwrite, RelativePaths);
finally
Stream.Free;
end;
if Assigned(FOnCompletedAction) then
FOnCompletedAction(Self);
end;
procedure TJvZlibMultiple.DoProgress(Position, Total: Integer);
begin
if Assigned(FOnProgress) then
FOnProgress(Self, Position, Total);
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvQZlibMultiple.pas,v $';
Revision: '$Revision: 1.17 $';
Date: '$Date: 2004/12/21 09:45:20 $';
LogPath: 'JVCL\run'
);
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -