首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用TFileStream delphi读取行

用TFileStream delphi读取行
EN

Stack Overflow用户
提问于 2012-07-22 11:45:57
回答 3查看 25.6K关注 0票数 3

如何使用某些行TFileStream读取文件。我读过有数百万个文件的行。所以我想在内存中播放,我将只使用

示例:

代码语言:javascript
复制
Line 1: 00 00 00 00 00 00 00 00
Line 2: 00 00 00 00 00 00 00 00
Line 3: 00 00 00 00 00 00 00 00
Line 4: 00 00 00 00 00 00 00 00
Line 5: 00 00 00 00 00 00 00 00

我读了第二行到第四行

我使用了函数TextFile,但它似乎很慢。刚刚找到了一个函数,可以读取TFileStream中的最后一行。

EN

回答 3

Stack Overflow用户

发布于 2012-07-22 15:14:33

您可以使用TFileStream类打开一个要读取的文件,如下所示...

代码语言:javascript
复制
FileStream := TFileStream.Create( 'MyBigTextFile.txt', fmOpenRead)

TFileStream不是一个引用计数的对象,所以一定要在完成后释放它,就像这样……

代码语言:javascript
复制
FileStream.Free

从这里开始,我将假设您的文件的字符编码是UTF-8,并且行尾终止是MS样式。如果没有,请相应调整,或更新您的问题。

您可以读取UTF-8字符的单个代码单元(与读取单个字符不同),如下所示:

代码语言:javascript
复制
var ch: ansichar;
FileStream.ReadBuffer( ch, 1);

你可以像这样读一行文本...

代码语言:javascript
复制
function ReadLine( var Stream: TStream; var Line: string): boolean;
var
  RawLine: UTF8String;
  ch: AnsiChar;
begin
result := False;
ch := #0;
while (Stream.Read( ch, 1) = 1) and (ch <> #13) do
  begin
  result := True;
  RawLine := RawLine + ch
  end;
Line := RawLine;
if ch = #13 then
  begin
  result := True;
  if (Stream.Read( ch, 1) = 1) and (ch <> #10) then
    Stream.Seek(-1, soCurrent) // unread it if not LF character.
  end
end;

要读取第2、3和4行,假设位置为0 ...

代码语言:javascript
复制
ReadLine( Stream, Line1);
ReadLine( Stream, Line2);
ReadLine( Stream, Line3);
ReadLine( Stream, Line4);
票数 12
EN

Stack Overflow用户

发布于 2012-07-23 16:51:42

您可以使用传统的文件操作。为了更快,你必须确保每一行都有相同大小的字节。

Blockread,BlockWrite,Seek是你可以查看的关键字。

Sample page for BlockRead

Sample page for Seek

票数 2
EN

Stack Overflow用户

发布于 2016-02-13 09:33:24

正如David解释的那样,Code Sean propose由于TFileStream.Read而变得很慢。但是如果你使用TMemoryStream而不是TFileStream,那么慢的Stream.Read就不那么重要了。在这种情况下,字符串操作占用了大部分时间。

如果您稍微更改代码,速度将提高2倍:

代码语言:javascript
复制
function ReadLine(Stream: TStream; var Line: string): boolean;
var
  ch: AnsiChar;
  StartPos, LineLen: integer;
begin
  result := False;
  StartPos := Stream.Position;
  ch := #0;
  while (Stream.Read( ch, 1) = 1) and (ch <> #13) do;
  LineLen := Stream.Position - StartPos;
  Stream.Position := StartPos;
  SetString(Line, NIL, LineLen);
  Stream.ReadBuffer(Line[1], LineLen);
  if ch = #13 then
    begin
    result := True;
    if (Stream.Read( ch, 1) = 1) and (ch <> #10) then
      Stream.Seek(-1, soCurrent) // unread it if not LF character.
    end
end;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11597634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档