2014-02-25 82 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