📄 umaptextfile.pas
字号:
unit UMapTextfile;
interface
uses Classes, Windows, sysUtils, Dialogs;
type
EMMError = class(Exception);
TMapTextfile = class
private
FFileName: string; //文件名称
FFileHandle: THandle; //映射文件的句柄
FMapFileHandle: THandle; //文件影射对象的句柄
FFileSize: integer; //文件的实际大小
FFileCreateSize: integer; //当创建文件时,文件的大小
FMapView: PByte; //文件数据的指针
FFileMode: Integer; //文件的访问模式
FData: PChar; //文件的数据指针
FPos: INTEGER; //文件的访问的当前位置
function CalcPos(pos: INTEGER): PCHAR; //返回当前指针的值
public
procedure open;
procedure Close;
function ReadChar: CHAR;
function ReadString: string;
procedure ReadLn(var str: string);
function ReadCharAt(pos: LONGINT): CHAR;
procedure ReadChars(str: PCHAR; pos, len: LONGINT);
function ReadStringAt(pos: LONGINT): string;
function GetSize: LONGINT;
function GetPos: LONGINT;
procedure SetPos(pos: LONGINT);
function EndOfFile: BOOLEAN;
function FindString(const str: string; pos, max: INTEGER): INTEGER;
procedure ReadBytes(var b; pos, len: LONGINT);
procedure WriteBytes(var b; pos, len: LONGINT);
property FileName: string read FFileName write FFileName;
property FileMode: Integer read FFileMode write FFileMode;
property FileCreateSize: Integer read FFileCreateSize write FFileCreateSize;
end;
implementation
//打开视图文件,并建立视图映射
procedure TMapTextFile.open;
var
ProtectAttr: DWORD; //对应于CreateFileMapping函数的保护属性
Access: Longint; // 对应于MapViewOfFile函数的视图访问模式
begin
//根据创建模式,创建或打开文件
if FFileMode = fmCreate then
FFileHandle := FileCreate(FFileName)
else
FFileHandle := FileOpen(FFileName, FFileMode);
if FFileHandle = INVALID_HANDLE_VALUE then
raise EMMError.Create('不能够创建或打开文件');
//得到文件大小
try
FFileSize := GetFileSize(FFileHandle, nil);
if FFileSize = 0 then
FFileSize := FFileCreateSize;
if FFileMode = fmOpenRead then
ProtectAttr := Page_ReadOnly
else
ProtectAttr := Page_ReadWrite;
//创建文件映射对象
FMapFileHandle := CreateFileMapping(FFileHandle, nil, ProtectAttr, 0, FFileSize, nil);
if FMapFileHandle = 0 then
raise EMMError.Create('创建文件映射失败');
finally
CloseHandle(FFileHandle);
end;
try
if FFileMode = fmOpenRead then
Access := File_Map_Read
else
Access := File_Map_All_Access;
//建立文件视图的映射
FMapView := MapViewOfFile(FMapFileHandle, Access, 0, 0, FFileSize);
if FMapView = nil then
raise EMMError.Create('将文件映射到进程空间失败');
finally
CloseHandle(FMapFileHandle);
end;
FData := PCHAR(FMapView);
FPos := 0;
end;
//取消文件视图的映射
procedure TMapTextFile.Close;
begin
if FMapView <> nil then
begin
UnmapViewOfFile(FMapView);
FMapView := nil;
end;
end;
//返回指定位置的数据
function TMapTextfile.CalcPos(pos: INTEGER): PCHAR;
begin
Result := nil;
if pos < 0 then pos := 0;
if pos > FFileSize then pos := FFileSize;
result := PCHAR(LONGINT(FMapView) + pos);
end;
//读取指定位置的数据
function TMapTextfile.ReadChar: CHAR;
begin
Result := #0;
FData := PCHAR(LONGINT(FMapView) + FPos);
Result := FData^;
INC(FPos);
end;
//读取指针后面的字符串
function TMapTextfile.ReadString: string;
begin
Result := '';
FData := PCHAR(LONGINT(FMapView) + FPos);
while (FPos < FFileSize) do
begin
case FData^ of
#0..#31: case FData^ of
#9, #27: Result := Result + FData^; // Tab und Escape weiterreichen
#10:
begin
INC(FPos);
EXIT;
end;
#13:
begin // Carriage Return terminiert
INC(FPos);
INC(FData);
if FData^ = #10 then INC(FPos);
EXIT;
end;
end;
else
Result := Result + FData^;
end;
INC(FPos);
INC(FData);
end;
end;
//读取指定位置的字符
function TMapTextfile.ReadCharAt(pos: LONGINT): CHAR;
begin
Result := CalcPos(pos)^
end;
//读取指定位置指定大小的数据缓冲区,存储为PChar类型
procedure TMapTextfile.ReadChars(str: PCHAR; pos, len: LONGINT);
var
i: INTEGER;
p: PCHAR;
begin
if len <= 0 then EXIT;
i := 0;
p := CalcPos(pos);
while (i <= FFileSize) and (i <= len) do
begin
str^ := p^;
INC(str);
INC(p);
INC(i);
end;
end;
//读取指定位置指定大小的数据缓冲区
procedure TMapTextfile.ReadBytes(var b; pos, len: LONGINT);
var
p: PCHAR;
begin
p := CalcPos(pos);
Move(p^, b, len);
end;
//在指定位置,写入数据
procedure TMapTextfile.WriteBytes(var b; pos, len: LONGINT);
var
p: PCHAR;
begin
p := CalcPos(pos);
Move(b, p^, len);
end;
//读取指定位置后的数据,以字符串的形式返回
function TMapTextfile.ReadStringAt(pos: LONGINT): string;
var
i: INTEGER;
p: PCHAR;
begin
Result := '';
p := CalcPos(pos);
i := 0;
while (i <= FFileSize) do
begin
case p^ of
#0..#31: case p^ of
#9,
#27: Result := Result + p^; // Tabs und Escape weiterreichen
#10,
#13: EXIT; // Linefeed and Carriage Return terminiert
end;
else Result := Result + p^;
end;
INC(p);
end;
end;
//返回值赋给str变量
procedure TMapTextfile.ReadLn(var str: string);
begin
str := ReadString;
end;
//读取文件大小
function TMapTextfile.GetSize: LONGINT;
begin
Result := FFileSize
end;
//得到文件的指针
function TMapTextfile.GetPos: LONGINT;
begin
Result := FPos
end;
//设置文件的指针
procedure TMapTextfile.SetPos(pos: LONGINT);
begin
if pos < 0 then pos := 0;
if pos > FFileSize then pos := FFileSize;
FPos := pos;
end;
//判断是指针是否到了文件的末尾
function TMapTextfile.EndOfFile: BOOLEAN;
begin
Result := FPos >= FFileSize
end;
//查找指定的字符串
function TMapTextfile.FindString(const str: string; pos, max: INTEGER): INTEGER;
var
s, l1, j: INTEGER;
p, x: PCHAR;
begin
Result := -1;
if max <= 0 then max := FFileSize;
if pos < 0 then pos := FPos;
if pos > max then EXIT;
x := PCHAR(str);
p := PCHAR(FMapView);
l1 := 0; while (x[l1] > #0) do INC(l1);
if (l1 > 0) then
begin
s := pos;
repeat (* 1 *)
j := 0;
while (s + j < max)
and (j < l1)
and (x[j] = p[s + j]) do begin
INC(j);
if (j = l1) then begin Result := s; EXIT; end;
end;
INC(s);
until s >= FFileSize;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -