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
答案是 属性 EndOfStream
在 TStreamReader
中声明,现在在与 TMemoryStream
.
不同的分支中
在 TStream
个后代中,您可以使用例如Position
和 Size
属性来确定您是否在流的末尾。
我制作了一个 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
答案是 属性 EndOfStream
在 TStreamReader
中声明,现在在与 TMemoryStream
.
在 TStream
个后代中,您可以使用例如Position
和 Size
属性来确定您是否在流的末尾。