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);
是什么原因呢?请有经验的朋友指点一下,谢谢先了

解决方案 »

  1.   

    如果流的数据比数组的容量少,必须设置charArr数组的初始值
      

  2.   

    SetLength(charArr,fileStream.Size+1);//加上这句
    fileStream.ReadBuffer(charArr, fileStream.Size);
      

  3.   

    设置过charArr := '';结果还是一样。
      

  4.   

    把charArr定义成
    charArr:array of char;
      

  5.   


    charArr是PChar类型啊,不能用这个SetLength。
      

  6.   

     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);
      

  7.   

    改charArr:array of Char;不过encryptData的0可能会认为是结束符,所以还要注意编码问题,是否是unicode编码,你用的2010吗
      

  8.   

    是的,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);但是出现内存访问违规。
      

  9.   

    charArr: array of AnsiChar;
    这样声明的。
      

  10.   

    SetLength(charArr, fileStream.Size + 1);这是干吗,为什么要加一,不要加
      

  11.   

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

  12.   

    2010的char是2字节,但是byte可不是2字节,所以你现在char和byte长度不一样,用ansichar
      

  13.   

    Move不是一字节一字节地操作的吗?如果Char = 2 字节,那它是不是也会一个Char分两次操作呢?另外,如果用AnsiChar,怎么把这个数组转到string中来?
      

  14.   

     找到问题症结了,这样写就搞定了
    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的最终实现者了。以上结论是通过多次实验得到的,希望对后来者有一定提示,我也是通过楼上诸位的讨论受到的启发,真的非常感谢这几位了!
      

  15.   

    另外,用不用array of Byte其实无所谓了,用PByte也是可以的。
    Move真的很好用,但一定得熟悉delphi的各种数据结构,特别是数组、动态数组、字符串。