我制作了一个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
的子类。为什么我不能用TMemoryStream调用类似while not(m.EndOfStream) do
的内容?
我无法理解MemoryStream和StreamReader之间的区别。根据我的理解,后者可以自动读取给定范围内的所有值,而第一个则不能。
注意:我已经阅读了文档,我可以拥有一个TStreamReader和一个TStreamWriter,当我需要创建一个包含一些数据的文件时,两者都很好。如果我对StreamReader有相同的行为,我就无法理解使用的内存流是什么。
答案 0 :(得分:2)
TStreamReader 是一个通用类,用于从任何流中读取文本/字符数据。它不支持流中的任何其他形式的数据,也不适用于任何其他形式的数据。
流本身可能是磁盘上的文件,也可能是网络上的数据或内存中的数据。存在不同的流类以提供对来自不同源的数据的流访问。
TMemoryStream 专门用于提供对内存中数据的访问,作为字节序列,可以是二进制数据或文本/字符数据,也可以是两者的混合。
答案 1 :(得分: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
后代中,您可以使用例如Position
和Size
属性,用于确定您是否位于流的末尾。