How to get data from a file without reading it into memory #167
Question
Is there a way to point a pointer to a text data file on a hard drive
without reading into memory. Here is the problem. I have a third-party
DLL that requires a pointer to a large char string 10000 + chars. If I
were to read into memory and then call the DLL it could cause problems.
You can use Mapped Files. A mapped file is a region in memory that is mapped to a file on disk. After you map a file to memory you get a pointer to the memory region and use it like any other pointer - Windows will load and unload pages from the file to memory as needed. Here is a very simple implementation of a mapped file. It is used only to read data from the file so you might want to change it to also allow writing. After you create an instance, the Content property is a pointer to the file content.
{ ... } type TMappedFile=class private FMapping: THandle; FContent: PChar; FSize: Integer; procedure MapFile(const FileName: string); public constructor Create(const FileName: string); destructor Destroy; override; property Content: PChar read FContent; property Size: Integer read FSize; end; implementation uses sysutils; { TMappedFile } constructor TMappedFile.Create(const FileName: string); begin inherited Create; MapFile(FileName); end; destructor TMappedFile.Destroy; begin UnmapViewOfFile(FContent); CloseHandle(FMapping); inherited; end; procedure TMappedFile.MapFile(const FileName: string); var FileHandle: THandle; begin FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite); Win32Check(FileHandle <> 0); try FSize := GetFileSize(FileHandle, nil); FMapping := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil); Win32Check(FMapping <> 0); finally FileClose(FileHandle); end; FContent := MapViewOfFile(FMapping, FILE_MAP_READ, 0, 0, 0); Win32Check(FContent <> nil); end;
Original resource: | The Delphi Pool |
---|---|
Author: | Eyal Post |
Added: | 2010/06/02 |
Last updated: | 2010/06/02 |