Delphi: Alternative to using Reset/ReadLn for text file reading

后端 未结 7 1207
时光取名叫无心
时光取名叫无心 2020-12-14 11:10

i want to process a text file line by line. In the olden days i loaded the file into a StringList:

slFile := TStringList.Create();
slFile.LoadFr         


        
相关标签:
7条回答
  • 2020-12-14 11:52

    You can use this sample code:

    TTextStream = class(TObject)
          private
            FHost: TStream;
            FOffset,FSize: Integer;
            FBuffer: array[0..1023] of Char;
            FEOF: Boolean;
            function FillBuffer: Boolean;
          protected
            property Host: TStream read FHost;
          public
            constructor Create(AHost: TStream);
            destructor Destroy; override;
            function ReadLn: string; overload;
            function ReadLn(out Data: string): Boolean; overload;
            property EOF: Boolean read FEOF;
            property HostStream: TStream read FHost;
            property Offset: Integer read FOffset write FOffset;
          end;
    
        { TTextStream }
    
        constructor TTextStream.Create(AHost: TStream);
        begin
          FHost := AHost;
          FillBuffer;
        end;
    
        destructor TTextStream.Destroy;
        begin
          FHost.Free;
          inherited Destroy;
        end;
    
        function TTextStream.FillBuffer: Boolean;
        begin
          FOffset := 0;
          FSize := FHost.Read(FBuffer,SizeOf(FBuffer));
          Result := FSize > 0;
          FEOF := Result;
        end;
    
        function TTextStream.ReadLn(out Data: string): Boolean;
        var
          Len, Start: Integer;
          EOLChar: Char;
        begin
          Data:='';
          Result:=False;
          repeat
            if FOffset>=FSize then
              if not FillBuffer then
                Exit; // no more data to read from stream -> exit
            Result:=True;
            Start:=FOffset;
            while (FOffset<FSize) and (not (FBuffer[FOffset] in [#13,#10])) do
              Inc(FOffset);
            Len:=FOffset-Start;
            if Len>0 then begin
              SetLength(Data,Length(Data)+Len);
              Move(FBuffer[Start],Data[Succ(Length(Data)-Len)],Len);
            end else
              Data:='';
          until FOffset<>FSize; // EOL char found
          EOLChar:=FBuffer[FOffset];
          Inc(FOffset);
          if (FOffset=FSize) then
            if not FillBuffer then
              Exit;
          if FBuffer[FOffset] in ([#13,#10]-[EOLChar]) then begin
            Inc(FOffset);
            if (FOffset=FSize) then
              FillBuffer;
          end;
        end;
    
        function TTextStream.ReadLn: string;
        begin
          ReadLn(Result);
        end;
    

    Usage:

    procedure ReadFileByLine(Filename: string);
    var
      sLine: string;
      tsFile: TTextStream;
    begin
      tsFile := TTextStream.Create(TFileStream.Create(Filename, fmOpenRead or    fmShareDenyWrite));
      try
        while tsFile.ReadLn(sLine) do
        begin
          //sLine is your line
        end;
      finally
        tsFile.Free;
      end;
    end;
    
    0 讨论(0)
提交回复
热议问题