分块压缩,适合很大的数据库压缩.
unit BsCompress;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
classes,
Forms,
zlib;
const
C_SIZE = 100000; // 1000000; //字节数大约为1m大小
function compressFile(SourFileName: string; DestFileName: string): boolean;
function XZIP(Sfile, Dfile: string; Compress: BOOL): BOOL;
function UnCompressit(const CompressedStream: TfileStream; var DestStream: TfileStream): boolean;
var
filename: array[0..255] of char;
fileSize, blockNum, ModNum: integer;
Buffer: PChar;
implementation
uses
Umain;
function compressFile(SourFileName: string; DestFileName: string): boolean; //压缩
var
InStream: TFileStream;
OutStream: TfileStream;
ZStream: TCompressionStream;
I: integer;
begin
result := false;
i := 0;
strpcopy(filename, Extractfilename(SourFileName)); //filename
if not fileexists(SourFileName) then exit;
try
Chdir(ExtractFilePath(ParamStr(0)));
if fileexists(destfilename) then deletefile(destfilename); //如目标文件存在就先删除
OutStream := Tfilestream.Create(destfilename, fmCreate or fmopenwrite);
InStream := TFileStream.Create(SourFileName, fmOpenRead or fmShareExclusive);
filesize := InStream.Size;
sendmessage(form1.Handle, pos_msg, filesize, 0);
blockNum := filesize div C_SIZE; //块
modnum := filesize mod C_SIZE; //mod datasize
if filesize <> 0 then
begin
OutStream.Write(filesize, SizeOf(filesize)); //在文件头写入源始文件大小,以便解压的时候读出源文件大小,否则就解压失败
// Outstream.Write(filename, sizeof(filename)); //write source filename to stream 256Byte
ZStream := TCompressionStream.Create(clDefault, OutStream); //clMax 压缩比最大 clNone, clFastest, clDefault, clMax
instream.Position := 0;
for i := 1 to blocknum do
begin
application.ProcessMessages;
postmessage(Form1.Handle, pos_msg, 0, i * c_size);
getmem(buffer, C_SIZE); //给指针分配源文件大小的空间
instream.Readbuffer(buffer^, C_SIZE);
ZStream.Writebuffer(buffer^, C_SIZE);
freemem(buffer);
end;
getmem(buffer, modnum); //剩下的数据
instream.Readbuffer(buffer^, modnum);
ZStream.Writebuffer(buffer^, modnum);
freemem(buffer);
postmessage(Form1.Handle, pos_msg, 0, 0);
outstream.Position := 0;
result := true;
end;
finally
instream.Free;
ZStream.Free;
end;
OutStream.Free;
end;
function UnCompressit(const CompressedStream: TfileStream; var DestStream: TfileStream): boolean; //解压
var
SourceStream: TDecompressionStream;
I: integer;
begin
result := false;
i := 0;
CompressedStream.ReadBuffer(filesize, sizeof(filesize)); //从文件头读出4个字节的数据,这一段是压缩时写进去的源文件大小
// CompressedStream.ReadBuffer(filename, sizeof(filename)); //read out filename
blocknum := filesize div C_size; //
modnum := filesize mod c_size; //mod datanum
sendmessage(form1.Handle, pos_msg, filesize, 0);
try
SourceStream := TDecompressionStream.Create(CompressedStream); //创建解压对象流
for i := 1 to blocknum do
begin
application.ProcessMessages; //交系统处理,以免出现画面停止现象
GetMem(Buffer, c_size); //分配源文件大小的内存
SourceStream.Readbuffer(Buffer^, c_size); //把解压流中的数据读count个到内存中,解压对象在读出数据的同时会自动解压文件
DestStream.Writebuffer(Buffer^, c_size); //把内存中的数据写count个到destStream中去
FreeMem(Buffer);
postmessage(Form1.Handle, pos_msg, 0, i * c_size);
end;
inc(i, modnum);
GetMem(Buffer, modnum);
SourceStream.Readbuffer(Buffer^, modnum);
DestStream.Writebuffer(Buffer^, modnum);
FreeMem(Buffer);
postmessage(form1.Handle, pos_msg, 0, 0);
DestStream.Position := 0; //指针指向
result := true;
finally
SourceStream.Free; //释放解压对象,节约内存
end;
end;
function XZIP(Sfile, Dfile: string; Compress: BOOL): BOOL; ///最新压缩CODE
var
mInputStream: TfileStream;
mOutputStream: TfileStream; //输出
Destdir: string;
begin
result := false;
if not fileexists(sfile) then exit;
DestDir := ExtractFilePath(dFile);
mOutputStream := Tfilestream.Create(dfile, fmCreate or fmopenwrite);
if not (Assigned(mInputStream) and Assigned(mOutputStream)) then Exit;
try
mInputStream := TfileStream.Create(sfile, fmOpenRead or fmShareExclusive);
if not UnCompressit(mInputStream, mOutputStream) then
begin
result := false;
exit;
end;
except
result := false;
exit;
end;
if not directoryexists(DestDir) then
begin
forcedirectories(DestDir);
result := true;
end
else
begin
if fileexists(dFile) then
begin
result := true;
end
else
exit;
end;
mOutputStream.Free;
mInputStream.Free;
result := true;
end;
end.