zoukankan      html  css  js  c++  java
  • 数据流的压缩、编码及传递困扰

    问题:

    在使用流据流对ClientDataSet.XMLData内容进行压缩、编码后无法正常取得原文内容。

    解决之道:

    数据流存入内容之前必须确定编码格式,至于想用何种编码并不重要,但必须明确的设置,否则在进行压缩、编码之后,还原原文时会有问题,按道理用默认编码是一样的,可是若没有明确设置流的存储编码就是有问题,这个问题困扰了我整整两个星期,啥办法都尝试过直到写出这个才算解决了。

    但至于用默认编码为何不行,现在还未弄明白,希望有网友能解惑。

    1、对字符串进行压缩、编码、传输的例子:

    procedure TTestMain.Button1Click(Sender: TObject);
    var
      s1,s2:String;
      d1,d2:string;
      SourceStream1,SourceStream2,SourceStream3:TStringStream;
      DestStream1,DestStream2,DestStream3:TStringStream;
    begin
      PageControl1.ActivePageIndex := 0;
      Memo2.Clear;
      s1 := Memo1.Text;
      {**************************************************************************
      TStream.Create之后,其position的值自动设置为0,其他操作必须人工干预position,
      否则position的取值为上一次操作之后的位置。
      关键点:数据流存入内容之前必须确定编码格式,至于想用何种编码并不重要,但必须
      明确的设置,否则在进行压缩、编码之后,还原原文时会有问题,按道理用默认编码是
      一样的,可是若没有明确设置流的存储编码就是有问题,这个问题困扰了我整整两个星
      期,啥办法都尝试过直到写出这个才算解决了。
      但至于用默认编码为何不行,现在还未弄明白,希望有网友能解惑。
      ***************************************************************************}
      //把s1字符串中的内容以UTF8的编码格式存入SourceStream1中。
      SourceStream1 := TStringStream.Create(s1,TEncoding.UTF8);//原始内容流
      SourceStream2 := TStringStream.Create('',TEncoding.ASCII);//用来存储压缩流
      SourceStream3 := TStringStream.Create('',TEncoding.UTF8);//用来存储Encode流,以便远程传递
      try
        System.ZLib.ZCompressStream(SourceStream1,SourceStream2);//压缩内容
    
        SourceStream2.Position := 0;
        Soap.EncdDecd.EncodeStream(SourceStream2,SourceStream3);//进行编码以便远程传递
    
        SourceStream3.Position := 0;
        s2 := SourceStream3.DataString;//取出编码后的内容,显示在Memo1中
        Memo1.Lines.Add('-------------以下为压缩并编码之后的内容:---------------');
        Memo1.Lines.Add(s2);
        ShowDataSize(Edit1,SourceStream1,SourceStream2,SourceStream3);
      finally
        SourceStream1.Free;
        SourceStream2.Free;
        SourceStream3.Free;
      end;
    
      {.................................................................
      .....s2的内容为Encode之后字符串,经过网络传递之后,传至客户端.....
      ..................................................................}
    
      d2 := s2; //取得从远程传递过来的经过了Encode编码之后的文本串
      Memo2.Text := d2;
      DestStream3 := TStringStream.Create(d2,TEncoding.UTF8);//读取远程经过了Encode编码之后的文本串
      DestStream2 := TStringStream.Create('',TEncoding.UTF8);//用来存储Decode之后的内容
      DestStream1 := TStringStream.Create('',TEncoding.UTF8);//用来存储解压缩流之后的原文内容
      try
        DestStream3.Position := 0;
        Soap.EncdDecd.DecodeStream(DestStream3,DestStream2);
    
        DestStream2.Position := 0;
        System.ZLib.ZDecompressStream(DestStream2,DestStream1);
    
        DestStream1.Position := 0;
        d1 := DestStream1.DataString;
        Memo2.Lines.Add('-------------以下为还原编码并解压后的内容:---------------');
        Memo2.Lines.Add(d1);
        ShowDataSize(Edit2,DestStream1,DestStream2,DestStream3);
      finally
        DestStream1.Free;
        DestStream2.Free;
        DestStream3.Free;
      end;
    end;
    
    1、对ClientDataSet记录集进行压缩、编码、传输的例子:

    procedure TTestMain.Button2Click(Sender: TObject);
    var
      s1,d1: String;
      sStream,sZipStream,sCodeStream,
      dStream,dZipStream,dCodeStream: TStringStream;
    begin
      PageControl1.ActivePageIndex := 1;
      if not ClientDataSet1.Active then
        ClientDataSet1.Active := True;
      {**************************************************************************
      TStream.Create之后,其position的值自动设置为0,其他操作必须人工干预position,
      否则position的取值为上一次操作之后的位置。
      关键点:数据流存入内容之前必须确定编码格式,至于想用何种编码并不重要,但必须
      明确的设置,否则在进行压缩、编码之后,还原原文时会有问题。
      ***************************************************************************}
    
      sStream := TStringStream.Create('',TEncoding.UTF8);
      sZipStream := TStringStream.Create('',TEncoding.ASCII);
      sCodeStream := TStringStream.Create('',TEncoding.ASCII);
      try
        ClientDataSet1.SaveToStream(sStream,dfXMLUTF8); //读取原始记录内容
    
        sStream.Position := 0;
        ZCompressStream(sStream,sZipStream);//压缩原文内容
    
        sZipStream.Position := 0;
        EncodeStream(sZipStream,sCodeStream);//编码以便网络传递
    
        //把sCodeStream流的文本内容取出为字符串类型,方便进行网络传输
        sCodeStream.Position := 0;
        s1 := sCodeStream.DataString;
    
        ShowDataSize(Edit1,sStream,sZipStream,sCodeStream);
      finally
        sStream.Free;
        sZipStream.Free;
        sCodeStream.Free;
      end;
    
      {...................................................................
      .....s1的内容为Encode之后的字符串,经过网络传递之后,传至客户端.....
      ....................................................................}
    
    
      d1 := s1; //接收
      dCodeStream := TStringStream.Create(d1,TEncoding.ASCII); //存入接收流中,此时流中为编码后的内容
      dZipStream := TStringStream.Create('',TEncoding.ASCII);
      dStream := TStringStream.Create('',TEncoding.UTF8);
      try
        DecodeStream(dCodeStream,dZipStream);//解码到dZipStream流中,此时dZipStream中为压缩流
    
        dZipStream.Position := 0;
        ZDecompressStream(dZipStream,dStream);//解压缩到dStream流中,此时dStream中为还原后的内容
    
        dStream.Position := 0;
        ClientDataSet2.LoadFromStream(dStream);
    
        ShowDataSize(Edit2,dStream,dZipStream,dCodeStream);
      finally
        dCodeStream.Free;
        dZipStream.Free;
        dStream.Free;
      end;
    end;
    
    Demo截图如下:

    Demo下载:Test.rar下载

  • 相关阅读:
    IE10标准模式不支持HTC (Html Components) ,升级重写Htc原有代码之一: 自定义属性
    Javascript 数组使用方法总结(转载)
    IE6IE9兼容性问题列表及解决办法_补充之六:锁表头的JQuery方案和非JQuery方案。(不支持IE6,7,8)
    软件国际化总结之一:数字与字符串之间的格式化和转化处理
    测试当前IE浏览器文档模型版本的js代码(使用documenMode)
    IE6IE9兼容性问题列表及解决办法_补充之五:在IE9下, disabled的文本框内容被选中后,其他控件无法获得焦点问题
    《从程序员到软件设计师的标志》(2010/05/10)
    《需求是软件设计师永远的痛》(2010/05/13)
    EOM与软件设计师开场白(2010/5/07)
    《软件设计师与程序员之间的拥抱和摆脱》(20101/05/11)
  • 原文地址:https://www.cnblogs.com/xieyunc/p/4438267.html
Copyright © 2011-2022 走看看