delphi2010里,怎样把TMemoryStream中的字符倒到string中?

biganchor 2010-06-03 05:25:33

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进制的软件打开过两种方式得到的字符了,编码也是不一样的,就是说上面的代码运作过程是经过了一个转换了。有高手知道怎么处理吗?在线急等了,谢谢各位先。
...全文
1002 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
biganchor 2010-06-09
  • 打赏
  • 举报
回复
问题有突破了,请看看我这里的回答
MinxSoft 2010-06-05
  • 打赏
  • 举报
回复
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
MinxSoft 2010-06-05
  • 打赏
  • 举报
回复
D2010里面的string是UnicodeString,MemoryStream里面的内容应该还是AnsiString,先读到一个AnsiString里面,再赋值给string就可以了
biganchor 2010-06-05
  • 打赏
  • 举报
回复
感谢楼上各位朋友的关注、参与,你们的想法给我很多提示。
biganchor 2010-06-05
  • 打赏
  • 举报
回复
看了下TMemoryStream.Read的实现代码,也是调用的Move来实现的;2010中的string虽然“支持”unicode,但它同时也可以存放AnsiString。现在还不能确定问题在哪里,打算先深入一下2010的字符串类型,再作一个总结了。
gzyzljk 2010-06-04
  • 打赏
  • 举报
回复
用一个字符串流从内存流中读取出来,再把字符串流转为string就可以了~~
starwlj 2010-06-04
  • 打赏
  • 举报
回复
补充一下,如果编码是Unicode而不是GB2312或者GBK编码,需要的话再转换一下.
starwlj 2010-06-04
  • 打赏
  • 举报
回复
我觉得应该可以跟踪下看看TMemoryStream中的内容到底是什么编码的

得到TMemoryStream中字符串的几个方法:
1. 把TMemoryStream.SaveToStream(TStringStream),然后通过TStringStream.DataString得到字符串

2. CopyMemory(Buffer,TMemoryStream.Memory,fsize);这个应该得到的是原编码内容
CopyMemory、MOVE和Read(Buffer^,fsize)应该是相同的效果,可以先跟踪下看看Buffer的内容,看看从TMemoryStream到Buffer 再到字符串的变化
Frank.WU 2010-06-04
  • 打赏
  • 举报
回复
你 AStream.SaveToFile 之后,用 UE 等软件查看开头的 4-8 字节,然后直接跟 TMemoryStream 中的字符开头的 4-8 字节进行一个对比,如果相同,则直接操作,如果不同,肯定就是编码不一样,要在操作的流之前添加编码的几个字节(例如UTF8 是 EF BB BF ,UNICODE 是 FF FE ,等)才行,所以我个人认为,用记事本能打开或者是网页用什么编码说明不了什么问题。
devhp 2010-06-04
  • 打赏
  • 举报
回复
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 }

不知道這個對你有沒有用?
iqyely 2010-06-04
  • 打赏
  • 举报
回复
来关注下。
yshuui 2010-06-03
  • 打赏
  • 举报
回复
对,我忘记了。这里应该是:
FResponseString := PAnsiChar(charBuffer);
不能用PChar转换,然后再用Utf8decode转换一下试试。
biganchor 2010-06-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 yshuui 的回复:]
这样写不行,PChar(charBuffer)可以理解为基于Bytes的,网页编码为gb2312,必须要进行转换才可以正常显示。
我觉得网页编码UTF-8更多吧,先用Utf8decode试试,再找找相关函数吧。
[/Quote]
我用delphi2010了,PChar相当于PWideChar了。
yshuui 2010-06-03
  • 打赏
  • 举报
回复
这样写不行,PChar(charBuffer)可以理解为基于Bytes的,网页编码为gb2312,必须要进行转换才可以正常显示。
我觉得网页编码UTF-8更多吧,先用Utf8decode试试,再找找相关函数吧。
biganchor 2010-06-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tjianliang 的回复:]
看一下SaveToFile的源码
[/Quote]

看也没意义吧?Stream的操作貌视是基于Byte的,它当然是原样把全部Byte存入文件里完事了吧。但这个网页是gb2312的,我需要把这些流存入一个string中,这当中应该是有一个转换过程的,就是不知道怎么转换呢?
biganchor 2010-06-03
  • 打赏
  • 举报
回复
GetMem(charBuffer, AStream.Size);
AStream.Read(charBuffer^, AStream.Size);
FResponseString := PChar(charBuffer);
FreeMem(charBuffer);

这样子改了下,还是不行,但是这次取到的编码跟上面的不一样了,貌视还不是gb2312的编码。
biganchor 2010-06-03
  • 打赏
  • 举报
回复
哦,好,我先试试
亮剑_ 2010-06-03
  • 打赏
  • 举报
回复
看一下SaveToFile的源码
bdmh 2010-06-03
  • 打赏
  • 举报
回复
TMemoryStream本身有read和write,把内容写到buffer里读出

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧