procedure GetStringFromStream(AStream: TMemoryStream);
var
  charBuffer: PAnsiChar;
begin
  SetLength(FResponseString, AStream.Size);
  GetMem(charBuffer, AStream.Size);
  Move(PAnsiChar(AStream.Memory)^, charBuffer^, AStream.Size);
  FResponseString := PChar(charBuffer);
  FreeMem(charBuffer);
end;
用上面的代码得到的是乱码,AStream中的数据中从一个网页上Get来的,网页的编码是gb2312。如果我这样操作AStream.SaveToFile,打开就是正确的代码。已经用16进制的软件打开过两种方式得到的字符了,编码也是不一样的,就是说上面的代码运作过程是经过了一个转换了。有高手知道怎么处理吗?在线急等了,谢谢各位先。

解决方案 »

  1.   

    TMemoryStream本身有read和write,把内容写到buffer里读出
      

  2.   

      GetMem(charBuffer, AStream.Size);
      AStream.Read(charBuffer^, AStream.Size);
      FResponseString := PChar(charBuffer);
      FreeMem(charBuffer);这样子改了下,还是不行,但是这次取到的编码跟上面的不一样了,貌视还不是gb2312的编码。
      

  3.   


    看也没意义吧?Stream的操作貌视是基于Byte的,它当然是原样把全部Byte存入文件里完事了吧。但这个网页是gb2312的,我需要把这些流存入一个string中,这当中应该是有一个转换过程的,就是不知道怎么转换呢?
      

  4.   

    这样写不行,PChar(charBuffer)可以理解为基于Bytes的,网页编码为gb2312,必须要进行转换才可以正常显示。
    我觉得网页编码UTF-8更多吧,先用Utf8decode试试,再找找相关函数吧。
      

  5.   

    我用delphi2010了,PChar相当于PWideChar了。
      

  6.   

    对,我忘记了。这里应该是:
    FResponseString := PAnsiChar(charBuffer);
    不能用PChar转换,然后再用Utf8decode转换一下试试。
      

  7.   

    function   StreamToString(mStream:   TStream):   string;   
    {   将内存流转换成字符串   }   
    var   
    I:   Integer;   
    begin   
    Result   :=   '';   
    if   not   Assigned(mStream)   then   Exit;   
    SetLength(Result,   mStream.Size);   
    for   I   :=   0   to   Pred(mStream.Size)   do   try   
    mStream.Position   :=   I;   
    mStream.Read(Result[Succ(I)],   1);   
    except   
    Result   :=   '';   
    end;   
    end;   {   StreamToString   }   不知道這個對你有沒有用?
      

  8.   

    你 AStream.SaveToFile 之后,用 UE 等软件查看开头的 4-8 字节,然后直接跟 TMemoryStream 中的字符开头的 4-8 字节进行一个对比,如果相同,则直接操作,如果不同,肯定就是编码不一样,要在操作的流之前添加编码的几个字节(例如UTF8 是 EF BB BF ,UNICODE 是 FF FE ,等)才行,所以我个人认为,用记事本能打开或者是网页用什么编码说明不了什么问题。
      

  9.   

    我觉得应该可以跟踪下看看TMemoryStream中的内容到底是什么编码的得到TMemoryStream中字符串的几个方法:
    1. 把TMemoryStream.SaveToStream(TStringStream),然后通过TStringStream.DataString得到字符串2. CopyMemory(Buffer,TMemoryStream.Memory,fsize);这个应该得到的是原编码内容
    CopyMemory、MOVE和Read(Buffer^,fsize)应该是相同的效果,可以先跟踪下看看Buffer的内容,看看从TMemoryStream到Buffer 再到字符串的变化
      

  10.   

    补充一下,如果编码是Unicode而不是GB2312或者GBK编码,需要的话再转换一下.
      

  11.   

    用一个字符串流从内存流中读取出来,再把字符串流转为string就可以了~~
      

  12.   

    D2010里面的string是UnicodeString,MemoryStream里面的内容应该还是AnsiString,先读到一个AnsiString里面,再赋值给string就可以了
      

  13.   

    procedure GetStringFromStream(AStream: TMemoryStream);
    var
      charBuffer: PAnsiChar;
    begin
      SetLength(FResponseString, AStream.Size);
      GetMem(charBuffer, AStream.Size);
      Move(PAnsiChar(AStream.Memory)^, charBuffer^, AStream.Size);
      FResponseString := PAnsiChar(charBuffer);
      FreeMem(charBuffer);
    end;
    我觉得是这样,Delphi7里面的PChar=PAnsiChar,Delphi2010里面的PChar=PWideChar
      

  14.   

    看了下TMemoryStream.Read的实现代码,也是调用的Move来实现的;2010中的string虽然“支持”unicode,但它同时也可以存放AnsiString。现在还不能确定问题在哪里,打算先深入一下2010的字符串类型,再作一个总结了。