2014-02-25 71 views
0

我所有, 我记得你,我约了ZLib问题的问题.... Delphi XE and ZLib Problems德尔福XE和zlib的问题(II)

大卫·赫弗南把我的方式与他的出色答卷(再次感谢@大卫) ...

总结答案... “这种流动压缩机看起来是这样的:字符串 - > UTF-8字节 - >压缩字节 - >字符串的base64显然 你反向的箭头进行解压缩。”

我不知道我必须张贴在同一职位或我必须附加这样的新问题......

嗯,我上周末的工作...

我跟着流串 - > UTF-8字节 - >压缩字节 - >字符串的base64

这是压缩功能和它的作品...

function CompressStrToCode64Str(const aText: string; aCompressionLevel: TZCompressionLevel): string; 
var 
    strStreamIN, 
    strStreamOUT: TStringStream; 
begin 
    result := ''; 
    /// Putting the string received to a Stream. 
    strStreamIN := TStringStream.Create(aText, TEncoding.UTF8); 
    try 
    /// Creating the output stream for compression. 
    strStreamOUT := TStringStream.Create('', TEncoding.UTF8); 
    try 
     /// Compressing streamIN to streamOUT 
     ZCompressStream(strStreamIN, strStreamOUT, aCompressionLevel); 
     /// Encoding to base64 for string handling. 
     result := string(EncodeBase64(strStreamOUT, strStreamOUT.Size)); 
    finally 
     strStreamOUT.Free; 
    end; 
    finally 
    strStreamIN.Free; 
    end; 
end; 

,这是解压缩功能...但它不起作用...(返回空字符串)

function TForm1.Code64StrToUncompressStr(Const aText: string): string; 
var 
    strStreamIN, 
    strStreamOUT: TStringStream; 
    data: TBytes; 
begin 
    result := ''; 
    /// Creating the input stream. 
    strStreamIN := TStringStream.Create('', TEncoding.UTF8); 
    try 
    /// Decoding base64 of received string to a TBytes 
    data := DecodeBase64(ansistring(aText)); 
    /// Putting the TBytes to a Stream 
    strStreamIN.Write(data[0], Length(data)); 
    /// Creating uncompressed stream 
    strStreamOUT := TStringStream.Create('', TEncoding.UTF8); 
    try 
     /// Decompressing streamIN to StreamOUT 
     ZDeCompressStream(strStreamIN, strStreamOUT); 
     result := strStreamOUT.DataString; 
    finally 
     strStreamOUT.Free; 
    end; 
    finally 
    strStreamIN.Free; 
    end; 
end; 

一些想法为什么不工作的解压缩功能。它返回一个空字符串。 TIA为您的耐心。

回答

2

这是我脑子里想的:

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Classes, ZLib, EncdDecd; 

function CompressAndEncodeString(const Str: string): string; 
var 
    Utf8Stream: TStringStream; 
    Compressed: TMemoryStream; 
    Base64Stream: TStringStream; 
begin 
    Utf8Stream := TStringStream.Create(Str, TEncoding.UTF8); 
    try 
    Compressed := TMemoryStream.Create; 
    try 
     ZCompressStream(Utf8Stream, Compressed); 
     Compressed.Position := 0; 
     Base64Stream := TStringStream.Create('', TEncoding.ASCII); 
     try 
     EncodeStream(Compressed, Base64Stream); 
     Result := Base64Stream.DataString; 
     finally 
     Base64Stream.Free; 
     end; 
    finally 
     Compressed.Free; 
    end; 
    finally 
    Utf8Stream.Free; 
    end; 
end; 

function DecodeAndDecompressString(const Str: string): string; 
var 
    Utf8Stream: TStringStream; 
    Compressed: TMemoryStream; 
    Base64Stream: TStringStream; 
begin 
    Base64Stream := TStringStream.Create(Str, TEncoding.ASCII); 
    try 
    Compressed := TMemoryStream.Create; 
    try 
     DecodeStream(Base64Stream, Compressed); 
     Compressed.Position := 0; 
     Utf8Stream := TStringStream.Create('', TEncoding.UTF8); 
     try 
     ZDecompressStream(Compressed, Utf8Stream); 
     Result := Utf8Stream.DataString; 
     finally 
     Utf8Stream.Free; 
     end; 
    finally 
     Compressed.Free; 
    end; 
    finally 
    Base64Stream.Free; 
    end; 
end; 

var 
    EncodedAndCompressed: AnsiString; 

begin 
    EncodedAndCompressed := CompressAndEncodeString('ZLib, Utf-8, compression test'); 
    Writeln(EncodedAndCompressed); 
    Writeln(DecodeAndDecompressString(EncodedAndCompressed)); 
    Readln; 
end. 

输出

 
eJyL8slM0lEILUnTtdBRSM7PLShKLS7OzM9TKEktLgEAjjwKMA== 
ZLib, Utf-8, compression test 

正如你所看到的,通过你包括Base64的时候,它是不是真的压缩。它可能是用更大的输入字符串进行压缩。这就是为什么我认为你更好地传输二进制文件,正如我在前面的问题中解释的。

+0

非常感谢@David。我看到我必须使用ASCII编码base64 ...我必须将其转换为base64以在CDATA中以XML格式发送压缩的文本,并且没有代码页的问题,我必须用大字符串尝试它,看看长度下降... – JosepMaria

+0

@JosepMaria实际上任何包含ASCII的8位编码都可以工作。所以你可以使用任何ANSI编码或UTF-8。但ASCII在语义上是正确的。如果你在CDATA中需要它,那么base 64可能是最好的选择。我期望更大的字符串,你会得到压缩。 –

+0

我已经结束了测试,运行非常非常好!在41KB的大消息中减少到8KB;并在12KB的中等消息减少到3KB ... 70%和80%之间的压缩!是惊人的!!再次感谢,不仅对代码,感谢教我(流)和编码... – JosepMaria