德尔福LZMA减压样品 [英] Delphi LZMA Decompression sample

查看:194
本文介绍了德尔福LZMA减压样品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这个线程链接中找到 delphi-zip 具有LZMA实现的库。但是我不能正确使用Decompression。
有些人可以使用这个库为我写一个解压缩样本吗?

I found in this thread link of the delphi-zip library that has implementation of LZMA. But I can't make proper use of Decompression from it. Can some one write a little decompression sample for me, using this library?

这是我的代码,它适用于压缩,但不适用于解压缩并返回0大小

Here is my code, it works for compression but didn't work for decompression and return 0 size

使用System.Zip.LZMA;

uses System.Zip.LZMA;

....

procedure TForm2.CompressProgress(Sender: TObject; const aPosition, aSize, aCompressedSize: UInt64);
begin
end;

procedure TForm2.DecompressProgress(Sender: TObject; const aPosition, aSize: UInt64);
begin
end;

procedure TForm2.CompressButton1Click(Sender: TObject);
var LZI: TLZMAEncoderStream;  OutStream, InStream: TMemoryStream;
begin
     OutStream:= TMemoryStream.Create;
     LZI := TLZMAEncoderStream.Create(OutStream,  CompressProgress);
     InStream:= TMemoryStream.Create;
     InStream.LoadFromFile('1.exe');
     InStream.Position := 0;
     LZI.Write(InStream, InStream.Size);
     OutStream.Position := 0;
     OutStream.SaveToFile('1.exe.lzma');
     InStream.Free;
     OutStream.Free;
     LZI.Free;
end;

procedure TForm2.DecompressButton2Click(Sender: TObject);
var Deca: TLZMADecoderStream;    Str1: TMemoryStream; S2 : TBytesStream;  J, I: Cardinal;
begin
    I := 0;
    Str1 := TMemoryStream.Create;
    Str1.LoadFromFile('1.exe.lzma');
    Str1.Position := 0;
    Deca:= TLZMADecoderStream.Create(Str1, DecompressProgress);

   S2   := TBytesStream.Create;
   J := Deca.Read(S2.Bytes, 0, i);

    Caption := IntToStr(J);

   S2.Position := 0;
   S2.SaveToFile('1.exe');

   Deca.Free;
   Str1.Free;
   S2.Free;
end;

我也试过这样做,但仍然没有工作

also I tried do like this, but still not work

procedure TForm2.Button2Click(Sender: TObject);
var Deca: TLZMADecoderStream;    Str1 : TMemoryStream;  S2:TBytesStream;  J, I: Cardinal;
begin
    I := 0;
    Str1 := TMemoryStream.Create;
    Str1.LoadFromFile('1.exe.lzma');
    Str1.Position := 0;
    Deca:= TLZMADecoderStream.Create(Str1, DeProgress);

   S2   := TBytesStream.Create;
   Deca.Position := 0;
   J := Deca.Read(S2.Bytes, 0, Deca.Size);
   Caption := IntToStr(J);
   S2.Position := 0;
   S2.SaveToFile('Dec0.exe');
   Deca.Free;
   Str1.Free;
   S2.Free;
end;


推荐答案

你要求读取零字节,这就是你所得到的。您将需要循环读取数据流中的数据块。保持循环直到读取返回零。请记住,读取返回读取的字节数。

You asked to read zero bytes and that's what you got. You will need to loop reading chunks of data out of the stream. Keep looping until Read returns zero. Remember that Read returns the number of bytes read.

我会使用这样的功能:

procedure LZMAcompress(InStream, OutStream: TStream);
var
  Encoder: TLZMAEncoderStream;
begin
  Encoder := TLZMAEncoderStream.Create(OutStream, nil);
  try
    Encoder.Write(InStream, InStream.Size);
  finally
    Encoder.Free;
  end;
end;

procedure LZMAdecompress(InStream, OutStream: TStream; Count: Int64);
const
  BufferSize = 1024*1024;
var
  Decoder: TLZMADecoderStream;
  Buffer: TBytes;
  BytesRead, BytesToRead: Integer;
begin
  Decoder := TLZMADecoderStream.Create(InStream, nil);
  try
    SetLength(Buffer, BufferSize);
    repeat
      BytesToRead := Min(Count, BufferSize);
      BytesRead := Decoder.Read(Buffer, BytesToRead);
      OutStream.Write(Buffer, BytesRead);
      dec(Count, BytesRead);
    until Count=0;
  finally
    Decoder.Free;
  end;
end;

这里绝对不需要内存流。需要两个文件流。

And there's absolutely no need for memory streams here. Two file streams are what is needed.

您将面临的主要问题是,您选择使用的库需要您知道要解压缩的文件大小。如果您尝试读取比可用的更多字节,则该库代码将进入非终止循环。因此,我的计数参数在 LZMAdecompress

The big issue that you will face is that the library you have chosen to use requires you to know how large the file is that you are decompressing. If you try to read more bytes than are available, then this library code enters a non-terminating loop. Hence my Count parameter in LZMAdecompress.

我的怀疑您选择使用的图书馆,或至少是您选择使用的课程,不适合您的需要。我只是快速浏览了代码,但对我来说看起来并不好看。当出现无效数据时,具有非终止循环的任何压缩库都不是很有用。我会在这个证据上回避这个图书馆。如果我是你,我会直接调用LZMA C API。

My suspicion is that the library that you have chosen to use, or at least the classes that you have chosen to use, are ill suited to your needs. I've only had a quick look through the code but it doesn't look good to me. Any compression library that has a non-terminating loop when presented with invalid data is not very useful. I would shun this library on this evidence. If I were you I would call the LZMA C API directly.

也许你的另一个问题是你对你正在使用的库做出错误的更改。不要这样做从github回到原始版本。

Perhaps your other problem is that you have made erroneous changes to the library that you are using. Don't do that. Go back to the original version from github.

这篇关于德尔福LZMA减压样品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆