为什么TStringStream.Bytes从什么人从“TStream.Read”获取不同(Why

2019-10-16 22:45发布

与TStringStream,所述bytes利用其Bytes属性不同于bytes使用提取TStream.Read 。 如下所示:

  1. bytes提取使用TStream.Read表示正确的数据。
  2. bytes使用其Bytes属性包含更多的数据。 (正确的最后一个字节bytes不同于错误的bytes

你能帮有关可能的原因发表评论? 非常感谢您的帮助!

PS:德尔福XE,Windows 7中(这似乎TStringStream早在Delphi 7中没有LoadFromFile或的SaveToFile。)

PS:样本文件可以从SkyDrive的下载: REF_EncodedSample&REF_DecodedSample 。 (zlib的压缩图像文件。)。

procedure CompareBytes_2;
var
  ss_1: TStringStream;
  ss_2: TStringStream;
  sbytes_Read: TBytes;
  sbytes_Property: TBytes;
  len_sbytes_Read: Integer;
  len_sbytes_Property: Integer;
  filename: string;
begin
  filename := 'REF_EncodedSample';  // textual data
//  filename := 'REF_DecodedSample';  // non-textual data

  ss_1 := TStringStream.Create;
  ss_1.LoadFromFile(filename);
  ss_2 := TStringStream.Create;
  ss_2.LoadFromFile(filename);

  ss_1.SaveToFile(filename+ '_CopyByStringStream_1');
  ss_2.SaveToFile(filename+ '_CopyByStringStream_2');

  len_sbytes_Read := ss_1.Size;
  SetLength(sbytes_Read, len_sbytes_Read);
  ss_1.Read(sbytes_Read[0], len_sbytes_Read);

  sbytes_Property := ss_2.Bytes;

  ShowMessage(
    BoolToStr(
      Length(sbytes_Read) = Length(sbytes_Property),
      True));

  ShowMessage(
    BoolToStr(
      sbytes_Read[len_sbytes_Read - 1] = sbytes_Property[len_sbytes_Read - 1],
      True));

  ss_1.Free;
  ss_2.Free;
end;

Answer 1:

字符串流的文件中指出:

字节属性返回,其中所述数据被存储在缓冲器中。 使用大小属性来寻找缓冲区数据的实际数额。

想必已分配缓冲区持有更多的空间比它实际需要。 只有缓冲区的第一大小字节包含有效的内容。


此外,呼叫ss_1.Read是有点毫无意义,因为长度(sbytes_Read)调用SetLength后不会改变。 而从流中读取当你使用ReadBuffer,而不是阅读。 同样,对于WriteBuffer。



Answer 2:

它是不可能的Read()比什么是在返回不同的字节Bytes属性,如Read()读取同一TBytes内存中对象的Bytes属性使用。

在D2009 +, TStringStream改变从TBytesStream,这反过来从导出导出TMemoryStream 。 这就是为什么TStringStreamLoadFromFile()SaveToFile()可用的方法了。 在早期版本中, TStringStream直接派生TStream来代替。 TStringStream现在存储编码的字节,而不是一个String像它在早期版本中。 该TStringStream构造器需要一个String作为输入,它编码的TBytes使用指定TEncoding (其中TEncoding.Default如果不指定使用TEncoding )。 该DataString属性的getter解码同样TBytesString使用TEncoding这是在构造函数中指定。 的LoadFromFile()SaveToFile()方法加载/保存TBytes原样不进行任何编码/解码全部执行。

所以,如果你调用LoadFromFile()它将存储文件数据,是流。 如果数据的编码不符TEncoding传递给构造函数中, DataStream属性将返回垃圾,但Bytes属性和Read()方法会工作得很好。

你的问题是你没有考虑到的Bytes属性返回整个内存块TMemoryStream分配用于其数据存储。 TMemoryStream分配基于增量块存储,所以可以为它分配更多的内存比它实际需要,这就是为什么它有独立的CapacitySize性。 该Capacity属性指示分配的内存的总容量,而Size属性指明了多少字节存储在所分配的内存。 当你调用LoadFromFile()Bytes房地产几乎总是比被加载的文件的大小。

所以基本上,你的代码是比较众所周知的“苹果”到“橘子”,这就是为什么你得到不好的结果。 您应该相应地修改你的代码,以解决之间的差别CapacitySize特性。 两者的内容TBytes变量将是完全相同高达Size字节 。 您比较多的是,这就是为什么你的代码失败。



文章来源: Why does TStringStream.Bytes differ from what one gets from 'TStream.Read'