【问题标题】:Delphi use memory stream to read linesDelphi 使用内存流读取行
【发布时间】:2017-04-08 21:18:47
【问题描述】:

我制作了一个 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;

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

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

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


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

【问题讨论】:

  • TMemoryStream 将数据存储在动态内存缓冲区中,该缓冲区通过类似文件的访问功能得到增强
  • Memo1.Lines.LoadFromFile() 怎么样?

标签: delphi delphi-10-seattle


【解决方案1】:

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

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

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

【讨论】:

  • aah 好的,所以当我必须读取文件(任何类型的扩展)时,TStreamReader 总是很好?
  • 不,不完全是。 TStreamReader 用于从 any 流中读取文本/字符数据。在构造函数中,您可以传递对流的引用(例如,TMemoryStream 的实例)。为方便起见,还提供了构造函数以允许您指定 filename - 这会导致 TStreamReader 在内部创建一个 TFileStream 以从该文件中读取,但这打破了流阅读器(通常不是此类)通常表示的“关注点分离”。
【解决方案2】:

回答您的实际问题:

我已经看到 MemoryStream(和其他类)都是子类 TStream 的。为什么我不能打电话给while not(m.EndOfStream) do 用 m 一个 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

答案是EndOfStream 属性在TStreamReader 中声明,与TMemoryStream 在不同的分支中。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 2015-05-15
    相关资源
    最近更新 更多