UMapTextFile.pas
上传用户:psxgmh
上传日期:2013-04-08
资源大小:15112k
文件大小:7k
源码类别:

Delphi/CppBuilder

开发平台:

Delphi

  1. unit UMapTextfile;
  2. interface
  3. uses Classes, Windows, sysUtils, Dialogs;
  4. type
  5.   EMMError = class(Exception);
  6.   TMapTextfile = class
  7.   private
  8.     FFileName: string; //文件名称
  9.     FFileHandle: THandle; //映射文件的句柄
  10.     FMapFileHandle: THandle; //文件影射对象的句柄
  11.     FFileSize: integer; //文件的实际大小
  12.     FFileCreateSize: integer; //当创建文件时,文件的大小
  13.     FMapView: PByte; //文件数据的指针
  14.     FFileMode: Integer; //文件的访问模式
  15.     FData: PChar; //文件的数据指针
  16.     FPos: INTEGER; //文件的访问的当前位置
  17.     function CalcPos(pos: INTEGER): PCHAR; //返回当前指针的值
  18.   public
  19.     procedure open;
  20.     procedure Close;
  21.     function ReadChar: CHAR;
  22.     function ReadString: string;
  23.     procedure ReadLn(var str: string);
  24.     function ReadCharAt(pos: LONGINT): CHAR;
  25.     procedure ReadChars(str: PCHAR; pos, len: LONGINT);
  26.     function ReadStringAt(pos: LONGINT): string;
  27.     function GetSize: LONGINT;
  28.     function GetPos: LONGINT;
  29.     procedure SetPos(pos: LONGINT);
  30.     function EndOfFile: BOOLEAN;
  31.     function FindString(const str: string; pos, max: INTEGER): INTEGER;
  32.     procedure ReadBytes(var b; pos, len: LONGINT);
  33.     procedure WriteBytes(var b; pos, len: LONGINT);
  34.     property FileName: string read FFileName write FFileName;
  35.     property FileMode: Integer read FFileMode write FFileMode;
  36.     property FileCreateSize: Integer read FFileCreateSize write FFileCreateSize;
  37.   end;
  38. implementation
  39. //打开视图文件,并建立视图映射
  40. procedure TMapTextFile.open;
  41. var
  42.   ProtectAttr: DWORD; //对应于CreateFileMapping函数的保护属性
  43.   Access: Longint; // 对应于MapViewOfFile函数的视图访问模式
  44. begin
  45. //根据创建模式,创建或打开文件
  46.   if FFileMode = fmCreate then
  47.     FFileHandle := FileCreate(FFileName)
  48.   else
  49.     FFileHandle := FileOpen(FFileName, FFileMode);
  50.   if FFileHandle = INVALID_HANDLE_VALUE then
  51.     raise EMMError.Create('不能够创建或打开文件');
  52. //得到文件大小
  53.   try
  54.     FFileSize := GetFileSize(FFileHandle, nil);
  55.     if FFileSize = 0 then
  56.       FFileSize := FFileCreateSize;
  57.     if FFileMode = fmOpenRead then
  58.       ProtectAttr := Page_ReadOnly
  59.     else
  60.       ProtectAttr := Page_ReadWrite;
  61. //创建文件映射对象
  62.     FMapFileHandle := CreateFileMapping(FFileHandle, nil, ProtectAttr, 0, FFileSize, nil);
  63.     if FMapFileHandle = 0 then
  64.       raise EMMError.Create('创建文件映射失败');
  65.   finally
  66.     CloseHandle(FFileHandle);
  67.   end;
  68.   try
  69.     if FFileMode = fmOpenRead then
  70.       Access := File_Map_Read
  71.     else
  72.       Access := File_Map_All_Access;
  73.   //建立文件视图的映射
  74.     FMapView := MapViewOfFile(FMapFileHandle, Access, 0, 0, FFileSize);
  75.     if FMapView = nil then
  76.       raise EMMError.Create('将文件映射到进程空间失败');
  77.   finally
  78.     CloseHandle(FMapFileHandle);
  79.   end;
  80.   FData := PCHAR(FMapView);
  81.   FPos := 0;
  82. end;
  83. //取消文件视图的映射
  84. procedure TMapTextFile.Close;
  85. begin
  86.   if FMapView <> nil then
  87.   begin
  88.     UnmapViewOfFile(FMapView);
  89.     FMapView := nil;
  90.   end;
  91. end;
  92. //返回指定位置的数据
  93. function TMapTextfile.CalcPos(pos: INTEGER): PCHAR;
  94. begin
  95.   Result := nil;
  96.   if pos < 0 then pos := 0;
  97.   if pos > FFileSize then pos := FFileSize;
  98.   result := PCHAR(LONGINT(FMapView) + pos);
  99. end;
  100. //读取指定位置的数据
  101. function TMapTextfile.ReadChar: CHAR;
  102. begin
  103.   Result := #0;
  104.   FData := PCHAR(LONGINT(FMapView) + FPos);
  105.   Result := FData^;
  106.   INC(FPos);
  107. end;
  108. //读取指针后面的字符串
  109. function TMapTextfile.ReadString: string;
  110. begin
  111.   Result := '';
  112.   FData := PCHAR(LONGINT(FMapView) + FPos);
  113.   while (FPos < FFileSize) do
  114.   begin
  115.     case FData^ of
  116.       #0..#31: case FData^ of
  117.           #9, #27: Result := Result + FData^; // Tab und Escape weiterreichen
  118.           #10:
  119.             begin
  120.               INC(FPos);
  121.               EXIT;
  122.             end;
  123.           #13:
  124.             begin // Carriage Return terminiert
  125.               INC(FPos);
  126.               INC(FData);
  127.               if FData^ = #10 then INC(FPos);
  128.               EXIT;
  129.             end;
  130.         end;
  131.     else
  132.       Result := Result + FData^;
  133.     end;
  134.     INC(FPos);
  135.     INC(FData);
  136.   end;
  137. end;
  138. //读取指定位置的字符
  139. function TMapTextfile.ReadCharAt(pos: LONGINT): CHAR;
  140. begin
  141.   Result := CalcPos(pos)^
  142. end;
  143. //读取指定位置指定大小的数据缓冲区,存储为PChar类型
  144. procedure TMapTextfile.ReadChars(str: PCHAR; pos, len: LONGINT);
  145. var
  146.   i: INTEGER;
  147.   p: PCHAR;
  148. begin
  149.   if len <= 0 then EXIT;
  150.   i := 0;
  151.   p := CalcPos(pos);
  152.   while (i <= FFileSize) and (i <= len) do
  153.   begin
  154.     str^ := p^;
  155.     INC(str);
  156.     INC(p);
  157.     INC(i);
  158.   end;
  159. end;
  160. //读取指定位置指定大小的数据缓冲区
  161. procedure TMapTextfile.ReadBytes(var b; pos, len: LONGINT);
  162. var
  163.   p: PCHAR;
  164. begin
  165.   p := CalcPos(pos);
  166.   Move(p^, b, len);
  167. end;
  168. //在指定位置,写入数据
  169. procedure TMapTextfile.WriteBytes(var b; pos, len: LONGINT);
  170. var
  171.   p: PCHAR;
  172. begin
  173.   p := CalcPos(pos);
  174.   Move(b, p^, len);
  175. end;
  176. //读取指定位置后的数据,以字符串的形式返回
  177. function TMapTextfile.ReadStringAt(pos: LONGINT): string;
  178. var
  179.   i: INTEGER;
  180.   p: PCHAR;
  181. begin
  182.   Result := '';
  183.   p := CalcPos(pos);
  184.   i := 0;
  185.   while (i <= FFileSize) do
  186.   begin
  187.     case p^ of
  188.       #0..#31: case p^ of
  189.           #9,
  190.             #27: Result := Result + p^; // Tabs und Escape weiterreichen
  191.           #10,
  192.             #13: EXIT; // Linefeed and Carriage Return terminiert
  193.         end;
  194.     else Result := Result + p^;
  195.     end;
  196.     INC(p);
  197.   end;
  198. end;
  199. //返回值赋给str变量
  200. procedure TMapTextfile.ReadLn(var str: string);
  201. begin
  202.   str := ReadString;
  203. end;
  204. //读取文件大小
  205. function TMapTextfile.GetSize: LONGINT;
  206. begin
  207.   Result := FFileSize
  208. end;
  209. //得到文件的指针
  210. function TMapTextfile.GetPos: LONGINT;
  211. begin
  212.   Result := FPos
  213. end;
  214. //设置文件的指针
  215. procedure TMapTextfile.SetPos(pos: LONGINT);
  216. begin
  217.   if pos < 0 then pos := 0;
  218.   if pos > FFileSize then pos := FFileSize;
  219.   FPos := pos;
  220. end;
  221. //判断是指针是否到了文件的末尾
  222. function TMapTextfile.EndOfFile: BOOLEAN;
  223. begin
  224.   Result := FPos >= FFileSize
  225. end;
  226. //查找指定的字符串
  227. function TMapTextfile.FindString(const str: string; pos, max: INTEGER): INTEGER;
  228. var
  229.   s, l1, j: INTEGER;
  230.   p, x: PCHAR;
  231. begin
  232.   Result := -1;
  233.   if max <= 0 then max := FFileSize;
  234.   if pos < 0 then pos := FPos;
  235.   if pos > max then EXIT;
  236.   x := PCHAR(str);
  237.   p := PCHAR(FMapView);
  238.   l1 := 0; while (x[l1] > #0) do INC(l1);
  239.   if (l1 > 0) then
  240.   begin
  241.     s := pos;
  242.     repeat (* 1 *)
  243.       j := 0;
  244.       while (s + j < max)
  245.         and (j < l1)
  246.         and (x[j] = p[s + j]) do begin
  247.         INC(j);
  248.         if (j = l1) then begin Result := s; EXIT; end;
  249.       end;
  250.       INC(s);
  251.     until s >= FFileSize;
  252.   end;
  253. end;
  254. end.