奇怪的流操作,请大家进来看看!

biganchor 2010-06-08 12:43:16

GetMem(charArr, decryptedDataLen); // charArr: PChar;

fileStream.Clear;
fileStream.WriteBuffer(encryptData, decryptedDataLen); // encryptData: array of Byte;里边保存的是97, 0, 98,0,99,0
fileStream.Position := 0;
fileStream.ReadBuffer(charArr, fileStream.Size); // 读完之后,charArr中已经是'abcұ篘㖄ꉱë딘Bུ'
s := string(charArr);
ShowMessage(s);


是什么原因呢?请有经验的朋友指点一下,谢谢先了
...全文
224 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
biganchor 2010-06-09
  • 打赏
  • 举报
回复
另外,用不用array of Byte其实无所谓了,用PByte也是可以的。
Move真的很好用,但一定得熟悉delphi的各种数据结构,特别是数组、动态数组、字符串。
biganchor 2010-06-09
  • 打赏
  • 举报
回复
找到问题症结了,这样写就搞定了
fileStream.Write( encryptData[0], Length(encryptData) );
这里的encryptData是动态数组,动态数组的第一个元素就是encryptData[0],而不是encryptData自身,因为delphi中实现动态数组和string是相似的,都有引用计数(生存期自管理)。这个问题明晰后,再看把动态数组中的字符编码(内码)直接Move入2010的UnicodeString(默认)是怎样的写法:

Move( ucsStr[1], charCode[0], Length(charCode) );

实践证明ucsStr的结果就是这个内码代表的Unicode字符串!!

注:Move是Stream.ReadBuffer、WriteBuffer的最终实现者了。

以上结论是通过多次实验得到的,希望对后来者有一定提示,我也是通过楼上诸位的讨论受到的启发,真的非常感谢这几位了!
biganchor 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 bdmh 的回复:]
2010的char是2字节,但是byte可不是2字节,所以你现在char和byte长度不一样,用ansichar
[/Quote]
Move不是一字节一字节地操作的吗?如果Char = 2 字节,那它是不是也会一个Char分两次操作呢?

另外,如果用AnsiChar,怎么把这个数组转到string中来?
bdmh 2010-06-08
  • 打赏
  • 举报
回复
2010的char是2字节,但是byte可不是2字节,所以你现在char和byte长度不一样,用ansichar
biganchor 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 bdmh 的回复:]
SetLength(charArr, fileStream.Size + 1);这是干吗,为什么要加一,不要加
[/Quote]
照6楼的朋友写的,确实不明白为什么加1。不加1好像也行。

但是都有内存访问出错的问题,就在那个循环那里。我用的是2010.
很奇怪,流的操作不是基于字节的吗?2010里应该是Char = 2字节,我用了charArr: array of Char,那个流写入应该如实写入就行了,但是会这样显示('a', 'b', 'c', '', '烥', '柣'),正常来说应该是显示('a', 'b', 'c')就行了吧?因为两个字节并成了一个字节了,

怎么会这样呢?
bdmh 2010-06-08
  • 打赏
  • 举报
回复
SetLength(charArr, fileStream.Size + 1);这是干吗,为什么要加一,不要加
biganchor 2010-06-08
  • 打赏
  • 举报
回复
charArr: array of AnsiChar;
这样声明的。
biganchor 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 bdmh 的回复:]
改charArr:array of Char;不过encryptData的0可能会认为是结束符,所以还要注意编码问题,是否是unicode编码,你用的2010吗
[/Quote]
是的,6楼说的方法是可以的。我这样写
fileStream.Clear;
fileStream.WriteBuffer(encryptData, decryptedDataLen);
fileStream.Position := 0;
SetLength(charArr, fileStream.Size + 1);
fileStream.ReadBuffer(charArr, fileStream.Size);
for i := 0 to High(charArr) do
s := s + charArr[i]; // 这里出现内存访问违规了

ShowMessage(s);

但是出现内存访问违规。
bdmh 2010-06-08
  • 打赏
  • 举报
回复
改charArr:array of Char;不过encryptData的0可能会认为是结束符,所以还要注意编码问题,是否是unicode编码,你用的2010吗
madyak 2010-06-08
  • 打赏
  • 举报
回复
GetMem(charArr, decryptedDataLen); // charArr: PChar;

fileStream.Clear;
fileStream.WriteBuffer(encryptData, decryptedDataLen); // encryptData: array of Byte;里边保存的是97, 0, 98,0,99,0
fileStream.Position := 0;
//改下面这句话
fileStream.ReadBuffer(charArr^, fileStream.Size); // 读完之后,charArr中已经是'abcұ篘㖄ꉱë딘Bུ'
s := string(charArr);
ShowMessage(s);

biganchor 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lovelymelon 的回复:]
SetLength(charArr,fileStream.Size+1);//加上这句
fileStream.ReadBuffer(charArr, fileStream.Size);
[/Quote]

charArr是PChar类型啊,不能用这个SetLength。
lovelymelon 2010-06-08
  • 打赏
  • 举报
回复
把charArr定义成
charArr:array of char;
biganchor 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sanguomi 的回复:]
decryptedDataLen 是多少
[/Quote]
设置过charArr := '';结果还是一样。
lovelymelon 2010-06-08
  • 打赏
  • 举报
回复
SetLength(charArr,fileStream.Size+1);//加上这句
fileStream.ReadBuffer(charArr, fileStream.Size);
biganchor 2010-06-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 sanguomi 的回复:]
decryptedDataLen 是多少
[/Quote]
是6
弘石 2010-06-08
  • 打赏
  • 举报
回复
如果流的数据比数组的容量少,必须设置charArr数组的初始值
sanguomi 2010-06-08
  • 打赏
  • 举报
回复
decryptedDataLen 是多少

5,391

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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