2008. május 23., péntek
How to read very large text files fast
Problem/Question/Abstract:
Does anyone know the fastest way to read large text files (10Mb) into a string. Readln is just too slow.
Answer:
Solve 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;
Solve 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}
CloseHandle(hFile);
{Close file handle - as long is view is open it will persist}
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;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése