会流的压缩解压的老大进来瞧瞧(97分)

  • 主题发起人 主题发起人 gdljf
  • 开始时间 开始时间
G

gdljf

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在EDIT1中输入字符后,点第一按钮压缩,压缩后的内容存入EDIT2中;点第二按钮解压,并把解压后的内容写入MEMO1中,即最后edit1中的内容跟memo1中的内容应该是一样的,但我在点第二按钮时DELPHI7提示出错,但却无法定位到出错的指令。请各位老大帮我看看这程序该怎么改正。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Zlib;
type
TForm1 = class(TForm)
Memo1: TMemo;
Edit1: TEdit;
Button1: TButton;
Edit2: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var ins,ous:tmemorystream;
ss:tstringstream;
cs:tcompressionstream;
begin
ins:=tmemorystream.Create ;
ous:=tmemorystream.Create ;
ss:=tstringstream.Create('');
ins.WriteBuffer(pchar(edit1.Text)^,length(edit1.Text));
cs:=tcompressionstream.Create(clmax,ous);
cs.CopyFrom(ins,0);
cs.Free;
ous.Position :=0;
ss.CopyFrom(ous,0);
edit2.Text :=ss.DataString ;
ins.Free ;
ous.Free;
ss.Free;
end;

procedure TForm1.Button2Click(Sender: TObject);
var ins,ous:tmemorystream;
ss:tstringstream;
cs:tdecompressionstream;
begin
ins:=tmemorystream.Create ;
ous:=tmemorystream.Create ;
ss:=tstringstream.Create('');
ins.WriteBuffer(pchar(edit2.Text)^,length(edit2.Text));
ins.Position :=0;
cs:=tdecompressionstream.Create(ins);
ous.CopyFrom(cs,cs.Size);
cs.Free;
ous.Position :=0;
ss.CopyFrom(ous,0);
memo1.Lines.Add(ss.DataString );
ins.Free ;
ous.Free;
ss.Free;
end;
end.
 
var
Form1: TForm1;
Ms: TMemoryStream;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
Cs: TCompressionStream;
Buff: PChar;
BufLen: Integer;
begin
BufLen := Length(Edit1.Text);
Ms := TMemoryStream.Create;
Ms.WriteBuffer(BufLen, SizeOf(BufLen));
CS := TCompressionStream.Create(clMax, Ms);
Cs.WriteBuffer(PChar(Edit1.Text)^, BufLen);
Cs.Free;
Buff := AllocMem(Ms.Size + 1 - 4);
Ms.Position := 4;
Ms.ReadBuffer(Buff^, Ms.Size - 4);
Edit2.Text := Buff;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
Cs: TDecompressionStream;
BufLen: Integer;
Buff: PChar;
begin
Ms.Position := 0;
Ms.ReadBuffer(BufLen, SizeOf(BufLen));
Buff := AllocMem(BufLen + 1);
Cs := TDecompressionStream.Create(Ms);
Cs.ReadBuffer(Buff^, BufLen);
Cs.Free;
Edit3.Text := Buff;
FreeMem(Buff);
Ms.Free;
end;
 
你的代码有几个问题:
1、经过压缩的数据是二进制数据,如果将它以string的形式在edit中显示出来会发生改变,
所以不能用edit中的数据进行解压,必需以流或缓冲区等可以完整保留二进制数据的变量保
存压缩后的数据。
2、zlib在解压时需要我们自已确定原数据大小,所以我们必需在流中保存原始数据大小的数
据。
另外,由于数据长度信息通常会有#0字符,所以如果直接将压缩后的数据转换成字符串通常是
空字符串无法显示,所以上面的代码在显示时忽略了前4个字节的数据长度数据。
 
同意楼上的兄弟说得对
 
谢谢远帆兄的分析,上面的例子是我在写压缩解压时用来试验的,我的程序想实现的是:
把一个字符串压缩后写到一个文本文件或INI的一行里(我不要压缩文件,要的只是压缩过的字符串,),然后在需要时把它读出来解压还原。
这需要三步走:
1。把输入的字符串压缩;
2。把压缩后的内容保存到某个文本文件或INI的一行中(这就是我在试验的时候为什么要把它在EDIT2中显示出来,我可以不需要显示的);
3。从文本文件或INI中读入压缩后的内容进行解压还原。
请帮忙研究一下,谢谢!
 
由于压缩后的数据二进制的,而不是文本的,所以注定不能采用文本文件(INI文件)。
如果必需写入文本文件,你可以采用base64之类的算法将压缩后的内容变成文本,但是这样
大小会大很多,压缩就变得没有意义。
所以,你应该用二进制文件,如果你只是要求不让人家看到内容,而不是减小文件体积,
你可以先加密再base64存入文本文件。
 
这样也行也老兄,就按压缩后用base64编码的办法,你能不能给我个直接可以用的(即从原字符串到压缩编码到目的字符串,再从目的字符串编译解压到原字符串),因为这两部分我都不熟悉,要用到没办法。
问题解决了我再开贴给你追加100分,谢谢你!
 
可是这样没有意义!如果用base64编码又何必压缩?
 
谢谢这位兄弟,你的答案不错,我也已经另外找解决的方法了,
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
669
import
I
I
回复
0
查看
782
import
I
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部