Today at work, you need to solve a problem: Compress and decompress a file, where all of the processes are based on memory. For this reason, basic compression work such as ziplib can not be used. Later, I found such a piece of code from the Internet.
Procedure Compressit (var compressedstream:tmemorystream; const compressionlevel:tcompressionlevel); The parameters are passed by the stream and the compression mode Var Sourcestream:tcompressionstream; Deststream:tmemorystream; Count:int64; Note that the original size of the int begin//Get stream is modified here, Count: = Compressedstream.size; Deststream: = tmemorystream.create; Sourcestream: = Tcompressionstream.create (CompressionLevel, Deststream); The original stream Compressedstream.savetostream (Sourcestream) is preserved in the try//sourcestream; The original flow is compressed, and the compressed flow sourcestream.free is stored in the Deststream; Compressedstream.clear; Writes the size Compressedstream.writebuffer (count, SizeOf (count)) of the original image; Writes a compressed stream Compressedstream.copyfrom (deststream, 0); Finally Deststream.free; End End Procedure Uncompressit (const compressedstream:tmemorystream; var uncompressedstream:tmemorystream); Parameters of the compressed stream, extracted after the flow of Var Sourcestream:tdecompressionstream; Deststream:tmemorystream; Buffer:pchar; Count:int64; Begin//Read the original dimension Compressedstream.readbuffer (count, SizeOf (count)) from the compressed image stream; Allocates a memory block Getmem (Buffer) to the original stream that will be read, based on its size Count); Deststream: = tmemorystream.create; Sourcestream: = Tdecompressionstream.create (Compressedstream); Try//compress the stream to be compressed, and then deposit in the Buffer memory block Sourcestream.readbuffer (buffer^, Count); Save the original stream to the Deststream stream Deststream.writebuffer (buffer^, Count); Deststream.position: = 0; Reset stream pointer//deststream.position: = Length (ver_info); Loading the image stream Uncompressedstream.loadfromstream (Deststream) from the Deststream stream; Finally Freemem (Buffer); Deststream.free; End End
Later, because of changes in requirements, it is also based on memory but requires a single compression and decompression of multiple files. The above method is not applicable. In the process of my online search to zipforg can solve this problem. So I downloaded the zipforge
function Compressitmultifilebyzipforge (str_needtocompress_filenamelist:tstringlist; str_zip_file_name:string): Boolean; var My_ms, My_dest:tmemorystream; Strzipfile, Str_cur_file_name, str_file_name:string; My_zipforge:tzipforge; I, I_file_count:integer; Is_ok:boolean; Begin Strzipfile: = Str_zip_file_name; My_zipforge: = Tzipforge.create (nil); I_file_count: = Str_needtocompress_filenamelist. Count; My_ms: = tmemorystream.create; My_dest: = tmemorystream.create; IS_OK: = True; Try begin//my_zipforge.filename: = Strzipfile; My_zipforge.inmemory: = true;//If it is based on the memory stream is important my_zipforge.openarchive (My_dest, True); If I_file_count = 0 THEN begin IS_OK: = False; End ELSE begin with I: = 0 to I_file_count-1 do begin str_file_name: = Str_needtocompress_filenamelist. Strings[i]; Str_cur_file_name: = Ghidepathprefix + str_file_name; My_ms: = Getmemorystreambyfilename (Str_cur_file_name); If My_ms. Size <> 0 THEN BEGIN My_zipforge.addfromstream (Str_file_name, My_ms, True); End My_ms. Clear; End If My_dest. Size <> 0 THEN begin DM. LionSunMANET.DiskManage.SaveFile (Str_zip_file_name, my_dest); IS_OK: = True; End ELSE begin IS_OK: = False; End End My_ms. Clear; My_dest. Clear; my_zipforge.closearchive; End finally begin My_ms. Free; My_dest. Free; End End End
The
Extracts some of the code as follows:
function Decompresssinglezipfilebyzipforge (str_needtodecompress_filename:string;str_zip_file_name:string): Boolean; var My_ms, My_dest:tmemorystream; Strzipfile, Str_dest_file_name, str_file_name:string; My_zipforge:tzipforge; Is_ok:boolean; Begin Strzipfile: = Str_zip_file_name; My_zipforge: = Tzipforge.create (nil); My_ms: = tmemorystream.create; My_dest: = tmemorystream.create; IS_OK: = True; The file name of the try Begin//zip file if DM. LionSunMANET.DiskManage.ReadFile (Strzipfile,my_ms) = 1 THEN begin//my_zipforge.filename: = Strzipfile; My_zipforge.inmemory: = true;//key//Open compressed document my_zipforge.openarchive (my_ms,false);//key Str_file_name: = Str_ Needtodecompress_filename; My_zipforge.extracttostream (str_file_name,my_dest); Str_dest_file_name: = Ghidepathprefix + str_file_name; My_dest. Position: = 0; Dm. LionSunMANET.DiskManage.SaveFile (str_dest_file_name,my_dest); My_dest. Clear; Turn off the compressed document My_ms. Clear; my_zipforge.closearchive; IS_OK: = True; End ELSE begin my_dest. Clear; My_ms. Clear; IS_OK: = False; End End Finally begin My_ms. Free; My_dest. Free; End End Result: = IS_OK; End