«« Site Rescued »»

While the site is still going to move from its current host, a new site will now take its place. More Info.

The new site may have less content, but the core will now remain. And it will now play nicely with phones! Keep an eye on the DelphiDabbler Blog for news.

» Help

How to read very large text files fast

   
Question
Does anyone know the fastest way to read large text files (10Mb) into a string. Readln is just too slow.

Answer 1

You may try this:

function R(const FileName: string): string;
var
  M: TFileStream;
begin
  M := TFileStream.Create(FileName, fmOpenRead);
  try
    SetLength(Result, M.Size);
    M.Read(Result[1], M.Size);
  finally
    M.Free;
  end;
end;

Tip by Christian Aymon

Answer 2

As an alternative to Christian's suggestion, you can also use a memory-mapped file:

function MMFileToString(const AFilename: string): string;
var
  hFile: THandle;
  hFileMap: THandle;
  hiSize: DWORD;
  loSize: DWORD;
  text: string;
  view: pointer;
begin
  Result := '';
  if AFilename = '' then
    Exit;
  if not FileExists(AFilename) then
    Exit;
  {Open the file}
  hFile := CreateFile(
    PChar(AFilename), GENERIC_READ, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
  );
  if hFile <> INVALID_HANDLE_VALUE then
  begin
    loSize := GetFileSize(hFile, @hiSize);
    {File was opened successfully, now map it:}
    hFileMap := CreateFileMapping(
      hFile, nil, PAGE_READONLY, hiSize, loSize, 'TextForString'
    );
    if (hFileMap <> 0) then
    begin
      if (GetLastError() = ERROR_ALREADY_EXISTS) then
      begin
        MessageDlg(
          'Mapping already exists - not created.', mtWarning, [mbOk], 0
        );
        CloseHandle(hFileMap)
      end
      else
      begin
        try
          {File mapped successfully, now map a view of the file into the
          address space:}
          view := MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
          if (view <> nil) then
          begin {View mapped successfully}
            {Close file handle - as long is view is open it will persist}
            CloseHandle(hFile);
            SetLength(Result, loSize);
            Move(view^, Result[1], loSize);
          end
          else
            MessageDlg(
              'Unable to map view of file. ' + SysErrorMessage(GetLastError),
              mtWarning, [mbOk], 0
            );
        finally
          UnmapViewOfFile(view);  {Close view}
          CloseHandle(hFileMap);  {Close mapping}
        end
      end
    end
    else
    begin
      MessageDlg(
        'Unable to create file mapping. ' + SysErrorMessage(GetLastError),
        mtWarning, [mbOk], 0
      );
    end;
  end
  else
  begin
    MessageDlg(
      'Unable to open file. ' + SysErrorMessage(GetLastError),
      mtWarning, [mbOk], 0
    );
  end;
end;

Tip by Ralph Friedman

Original resource: The Delphi Pool
Author: Various
Added: 2010-06-02
Last updated: 2010-06-02

« Return to contents »