Author: Jonas Bilinkevicius
Is there a way to point a pointer to a text data file on a hard drive with out
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.
Answer:
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 - Window 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.
1 { ... }2 type3 TMappedFile = class4 private5 FMapping: THandle;
6 FContent: PChar;
7 FSize: Integer;
8 procedure MapFile(const FileName: string);
9 public10 constructor Create(const FileName: string);
11 destructor Destroy; override;
12 property Content: PChar read FContent;
13 property Size: Integer read FSize;
14 end;
15 16 implementation17 18 uses19 sysutils;
20 21 { TMappedFile }22 23 constructor TMappedFile.Create(const FileName: string);
24 begin25 inherited Create;
26 MapFile(FileName);
27 end;
28 29 destructor TMappedFile.Destroy;
30 begin31 UnmapViewOfFile(FContent);
32 CloseHandle(FMapping);
33 inherited;
34 end;
35 36 procedure TMappedFile.MapFile(const FileName: string);
37 var38 FileHandle: THandle;
39 begin40 FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyWrite);
41 Win32Check(FileHandle <> 0);
42 try43 FSize := GetFileSize(FileHandle, nil);
44 FMapping := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
45 Win32Check(FMapping <> 0);
46 finally47 FileClose(FileHandle);
48 end;
49 FContent := MapViewOfFile(FMapping, FILE_MAP_READ, 0, 0, 0);
50 Win32Check(FContent <> nil);
51 end;