⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umaptextfile.pas

📁 《Delphi 7经典问题解析》源代码 第一到七章 基础篇源程序 应用篇源程序
💻 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 + -