我想在二进制数据中解压缩LZ4原始流。我阅读了文档并提出了以下功能。根据代码,它应该继续解压缩,直到它用完压缩数据,但它不会。我究竟做错了什么?另外,我想为压缩大小添加一个writeln。
function Try(inStream: TMemorySTream): Boolean;
var
i, j, k: int64;
orig_buff: Pansichar;
compressed_buff: Pansichar;
lz4StreamDecode: PLZ4_streamDecode_t;
begin
result := false;
lz4StreamDecode := LZ4_createStreamDecode();
k := 0;
while True do
begin
orig_buff := allocmem(100);
compressed_buff := allocmem(4064);
j := inStream.Read(orig_buff^, 100);
i := lz4.LZ4_decompress_safe_continue(lz4StreamDecode, orig_buff,
compressed_buff, j, 4064);
Freemem(orig_buff);
Freemem(compressed_buff);
if i <= 0 then
break;
inc(k);
end;
if k <> 0 then
result := True;
LZ4_freeStreamDecode(lz4StreamDecode);
end;
编辑1:删除了释放输出缓冲区(临时缓冲区)的部分,仍然存在问题,而不是解压缩整个流然后退出,它只是事先退出循环。
function Try(inStream: TMemorySTream): Boolean;
var
i, j, k: int64;
orig_buff: Pansichar;
compressed_buff: Pansichar;
lz4StreamDecode: PLZ4_streamDecode_t;
begin
result := false;
lz4StreamDecode := LZ4_createStreamDecode();
compressed_buff := allocmem(64 * 1024 * 1024);
k := 0;
while True do
begin
orig_buff := allocmem(100);
j := inStream.Read(orig_buff^, 100);
i := lz4.LZ4_decompress_safe_continue(lz4StreamDecode, orig_buff,
compressed_buff, j, (64 * 1024 * 1024));
Freemem(orig_buff);
if i <= 0 then
break;
inc(k);
end;
if k <> 0 then
result := True;
Freemem(compressed_buff);
LZ4_freeStreamDecode(lz4StreamDecode);
end;
答案 0 :(得分:1)
LZ4_Decompress_safe_continue使用'先前的内存块',因为压缩也依赖于它。你正在摧毁那块记忆块。你不能这样做。相反,你应该使用两个缓冲区并在它们之间切换。您应该在开始之前创建缓冲区,并且只在解压缩结束时销毁它们。你说你已经阅读了手册。我认为你没有。它给出了一个明确的例子,并解释了它是如何工作的。
这是我修改你的功能的方法。对不起 - 无法测试
注意我正在使用2个缓冲区并在它们之间切换。这是你缺少的事情之一
另外我不会将Try用作函数名,它是一个保留字!
function XTry(inStream: TMemorySTream): Boolean;
var
i, j, k: int64;
orig_buff: Pansichar;
compressed_buff1, compressed_buff2: Pansichar;
lz4StreamDecode: PLZ4_streamDecode_t;
begin
result := false;
lz4StreamDecode := LZ4_createStreamDecode();
orig_buff := allocMem( 128 *1024 );
compressed_buff1 := allocmem(1024 * 1024);
compressed_buff2 := allocmem(1024 * 1024);
k := 0;
while True do
begin
j := inStream.Read(orig_buff^, 128*1024);
i := lz4.LZ4_decompress_safe_continue(lz4StreamDecode, orig_buff,
compressed_buff1, j, 4096); // <<<< Note 1st buffer
if i <= 0 then
break;
inc(k);
j := inStream.Read(orig_buff^, 128*1024);
i := lz4.LZ4_decompress_safe_continue(lz4StreamDecode, orig_buff,
compressed_buff2, j, 4096); // Note 2nd buffer
if i <= 0 then
break;
inc(k);
end;
if k <> 0 then
result := True;
LZ4_freeStreamDecode(lz4StreamDecode);
Freemem(compressed_buff1);
Freemem(compressed_buff2);
Freemem(orig_buff);
end;
显然这可以清理很多 - 我只想保持尽可能接近原始代码