Delphi 使用内存流读取行

Delphi use memory stream to read lines

我制作了一个 C++ 程序,它使用 ofstream 在我的磁盘中创建 2 个文件:一个名为 details.obf,另一个名为 records.txt。文件详细信息内部只有 1 行(1 个整数),文件 records.txt 的行数不固定(它们都是字符串)。


使用下面的代码我可以获得文件详细信息中的值。这很简单,我正在使用 MemoryStream。

m := TMemoryStream.Create;
try

 try
  m.LoadFromFile(TPath.Combine(TPath.GetHomePath, 'details.obf'));
  m.Read(i, sizeOf(i));
  //other stuff...
 except
  //...
 end;

finally
 m.Free;
end;

我正在使用下面的代码读取记录文件的内容:

a := TStreamReader.Create('C:\Users\betom\Desktop\records.txt');
 try

  while not(a.EndOfStream) do
   begin
    Memo1.Lines.Add(a.ReadLine);
   end;

 finally
  a.Free;
 end;

在第二个代码块中,我使用了不同的 class (TStreamReader),并且我在查看 embarcadero 的文档时编写了该代码。我不得不使用 while not(a.EndOfStream) do 因为 records.txt 的长度未知。

我看到 MemoryStream(和其他 classes)都是 TStream 的子classes。为什么我不能用 TMemoryStream 调用 while not(m.EndOfStream) do 之类的东西?

我无法理解 MemoryStream 和 StreamReader 之间的区别。据我了解,后者可以自动读取给定范围内的所有值,而第一个则不能。


注意:我已经阅读了文档,我可以拥有一个 TStreamReader 和一个 TStreamWriter,当我需要创建一个包含一些数据的文件时,两者都可以。如果我对 StreamReader 有相同的行为,我就无法理解 memorystream 的用途。

TStreamReader 是一个通用的 class 用于从 any 流中读取 text/character 数据。它不支持流中的任何其他形式的数据,也不打算与任何其他形式的数据一起使用。

流本身可能是磁盘上的文件或网络上的数据或内存中的数据。存在不同的流 classes 以提供对来自这些不同来源的数据的流访问。

TMemoryStream 专门用于提供对内存中字节序列数据的访问,这些数据可以是二进制数据或 text/character 数据或两者的混合。

回答您的实际问题:

I have seen that MemoryStream (and other classes) are all subclasses of TStream. Why I cannot call something like while not(m.EndOfStream) do with m a TMemoryStream?

首先更正。 TMemoryStream 一些 其他流操作 类(例如 TFileStream)继承自 TStream 是正确的。然而,TStreamReader(和 TStringReader)并非如此。这些继承自 TTextReader,与 TTextWriter 及其后代 TStreamWriter 和 TStringWriter 一起存在主要是为了 .Net 用户提供熟悉的 类。

这是一些讨论的层次结构 类:

TObject
    TStream
        TCustomMemoryStream
            TMemoryStream
                TBytesStream
                    TStringStream
        THandleStream
            TFileStream
        TWinSocketStream
        TOleStream
    TTextReader
        TStreamReader
        TStringReader
    TBinaryReader

答案是 属性 EndOfStreamTStreamReader 中声明,现在在与 TMemoryStream.

不同的分支中

TStream 个后代中,您可以使用例如PositionSize 属性来确定您是否在流的末尾。