大悟还俗

邮箱 key_ok@qq.com 我的收集 http://pan.baidu.com/share/home?uk=1177427271
  新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于使用MAPVIEWOFFILE大文件的读写(DELPHI版)

Posted on 2013-10-21 16:38  大悟还俗_2  阅读(1703)  评论(0编辑  收藏  举报
unit filemap;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;
const
    fileName = 'myTest.txt';
type
  TForm1 = class(TForm)
    btnUpper: TButton;
    btnLower: TButton;
    txtContent: TMemo;
    Label1: TLabel;
    btnClose: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnUpperClick(Sender: TObject);
    procedure btnLowerClick(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
  private
    { Private declarations }
  public
    UCase:Boolean;
    procedure ChangeFileCase;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// 全文中的txtContent.Lines.LoadFromFile(fileName)其目的只是为了显示文件修改结果

procedure TForm1.FormCreate(Sender: TObject);
begin
    txtContent.Clear();
    txtContent.Lines.LoadFromFile(fileName);
    //缺省将其转变为大写
    UCase := True;
end;

procedure TForm1.btnUpperClick(Sender: TObject);
begin
    UCase := true;
    ChangeFileCase;
end;

procedure TForm1.btnLowerClick(Sender: TObject);
begin
    UCase := false;
    ChangeFileCase;
end;

procedure Tform1.ChangeFileCase;//这个是本示例文件的核心运算部分
var
    FFileHandle : THandle;
    FMapHandle : THandle;
    FFileSize : Integer;
    FData : PByte;
    PData : PChar;
begin
//-------------------1 判断文件是否存在----------------------//
    if not FileExists(fileName) then
        raise Exception.Create('文件不存在!')
    else
//-------------------2 使用FileOpen获取一个文件HANDLE--------//
        FFileHandle := FileOPen(fileName,fmOPenReadWrite);
    //如果创建文件失败,就抛出一个异常
    if FFileHandle = INVALID_HANDLE_VALUE then
        raise Exception.Create('打开或创建文件失败!');
//-------------------3 使用CreateFileMapping创建一个刚才用FileOpen创建的HANDLE的文件映射对象--

-//
    try
        FFileSize := GetFileSize(FFileHandle,nil);
        FMapHandle := CreateFileMapping(FFileHandle,nil,PAGE_READWRITE,0,FFileSize,nil);

        if FMapHandle = 0 then
            raise Exception.Create('创建内存映射文件失败!');
    finally
        CloseHandle(FFileHandle);
    end;
//-------------------4 使用MapViewOfFile创建一个CreateFileMapping建立的HANDLE的映射文件的视图到

进程的地址空间------//
    try
        FData := MapViewOfFile(FMapHandle,FILE_MAP_ALL_ACCESS,0,0,FFileSize);
        if FData = nil then
            raise Exception.Create('映射文件失败!');
    finally
        CloseHandle(FMapHandle);
    end;
//-------------------5 对MapViewOfFile返回的指针做相应的运算操作------//
    try
        PData := PChar(FData);
        inc(PData,FFileSize);
        PData^ := #0;

        if UCase then
            StrUpper(PChar(FData))
        else
            StrLower(PChar(FData));
    finally
//-------------------6 取消文件视图的映射------//
        UnmapViewOfFile(FData);
    end;
    txtContent.Lines.Clear();
    txtContent.Lines.LoadFromFile(fileName);
end;

procedure TForm1.btnCloseClick(Sender: TObject);
begin
    Form1.Close();
end;

end.

{
//-------------------------------------------------------//
在做指针具体运算时,可以采用这样直接获取该指针处的某一类型的值
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
     p: Pointer;
begin
   i := 12345678;
   p := @i;
   showmessage(inttostr(integer(p)));   //俺的电脑上1242664,这是一个地址
   showmessage(inttostr(Pinteger(p)^));   //12345678
   showmessage(inttostr(PWord(p)^)); //24910
end;

Pinteger(p)^表示指针P处取得一个Integer值
PWord(p)^表示指针P处取得一个Word值
在windows.pas和system.pas中还定义了很多指针类型如下
  PInteger      = ^Integer;     {$NODEFINE PInteger}    { defined in sysmac.h }
  PCardinal     = ^Cardinal;
  PWord         = ^Word;
  PSmallInt     = ^SmallInt;    {$NODEFINE PSmallInt}   { defined in sysmac.h }
  {$POINTERMATH ON}
  PByte         = ^Byte;        {$NODEFINE PByte}       { defined in sysmac.h }
  {$POINTERMATH OFF}
  PShortInt     = ^ShortInt;    {$NODEFINE PShortInt}   { defined in sysmac.h }
  PInt64        = ^Int64;       {$NODEFINE PInt64}      { defined in sysmac.h }
  PUInt64       = ^UInt64;
  PLongWord     = ^LongWord;    {$NODEFINE PLongWord}   { defined in sysmac.h }
  PSingle       = ^Single;      {$NODEFINE PSingle}     { defined in sysmac.h }
  PDouble       = ^Double;      {$NODEFINE PDouble}     { defined in sysmac.h }
  PDate         = ^Doub
View Code