procedure TForm1.UpdateFile(Input: pointer; Length: Integer);
var
  p:PByte;
  I:Integer;
begin
    p:= PByte(Input);
    for i := 0 to Length - 1 do
    begin
    //处理p^的数据;这也是要保存的数据
    inc(p);
    end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
  FileHandle: THandle;
  MapHandle: THandle;
  ViewPointer: pointer;
  N:String;
begin
  n:=Edit1.text;
  FileHandle := CreateFile(PChar(N), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
    nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
  if FileHandle <> INVALID_HANDLE_VALUE then try
    MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
    if MapHandle <> 0 then try
      ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
      //如何映像大文件,>于4G、10G等???
      if ViewPointer <> nil then
      begin
        try
        UpdateFile(ViewPointer, GetFileSize(FileHandle, nil));
        //UpdateFile(ViewPointer, 1024*30000);
        finally
          UnmapViewOfFile(ViewPointer);
        end;
      end;
    finally
      CloseHandle(MapHandle);
    end;
  finally
    CloseHandle(FileHandle);
  end;
end;
如何映像大文件,>于4G、10G等???
我想文件在UpdateFile里对数据进行处理后,怎样将数据保存为文件?

解决方案 »

  1.   

    楼主为什么不在google上搜索一下呢 到处都是答案
      

  2.   

    文件映射要映射8G的文件需要分段映射,具体参数在MapViewOfFile最后三个参数。
      

  3.   

    CreateFileMapping(
      hFile:THandle;
      lpFileMappingAttributes:PSecurityAttributes;
      flProtect:DWORD;
      dwMaximumSizeHigh:DWORD;
      dwMaximumSizeLow:DWORD;
      lpName:PChar
    ):THandle;
    当文件大于4GB时,参数dwMaximumSizeHigh用于指定文件映像的高32位,dwMaximumSizeLow指定低32位
      

  4.   

    给你几个关键函数,你看一下就明白了:procedure TMappingFileStream.MappingFile;
    var
      pName: PChar;
    begin
      if FFileHandle = 0 then exit;   //文件句柄为空,退出;  //创建映射文件;
      if IsShareMem then
      begin
        pName := PChar(FMappingName);
        FMapHandle := CreateFileMapping(FFileHandle, nil, GetFileMappingMode,
          Int64Rec(FMapFileTotalSize).Hi, Int64Rec(FMapFileTotalSize).Lo, pName);
        if (FMapHandle <> 0) and (GetLastError = ERROR_ALREADY_EXISTS) then
        begin
          CloseHandle(FMapHandle);
          FMapHandle := 0;
          FMapHandle := OpenFileMapping(GetFileMapViewMode, False, pName);
        end;
      end
      else
        FMapHandle := CreateFileMapping(FFileHandle, nil, GetFileMappingMode,
          Int64Rec(FMapFileTotalSize).Hi, Int64Rec(FMapFileTotalSize).Lo, nil);  ViewPage;
    end;procedure TMappingFileStream.ViewPage;
    begin
      if FMapHandle = 0 then exit;
      FPageStartPos := MapViewOfFile(FMapHandle, GetFileMapViewMode,
        Int64Rec(FPageStartOffset).Hi, Int64Rec(FPageStartOffset).Lo, FPageFactSize);
      FPageCurrPos := FPageStartPos;
      if FFileHeaderEnabled then
        FFileHeader := MapViewOfFile(FMapHandle, GetFileMapViewMode, 0, 0, FFileHeaderSize);
    end;剩下的逻辑你自己封装吧,道理是先映射文件的一部分,然后独到后面在映射剩下的一部分。
      

  5.   

    http://blog.sina.com.cn/iamduo
    我的博客里,留下了内存映射的研习代码。
    现在打不开,没办法给你具体的网址。
    有机会可以去看看。
    我得到的结论是,内存映射和TMemoryStream 差不多效率。
      

  6.   

    1、创建内存映射的API函数 
    This function creates a named or unnamed file-mapping object for the specified file. HANDLE CreateFileMapping( 
    //通过调用fileopen or FileCreate后返回的文件句柄,如果是内存,则//$FFFFFFFF 
      HANDLE hFile,  
       //安全性结构,一般null 
      LPSECURITY_ATTRIBUTES lpFileMappingAttributes,  
       //文件试图的保护类型,PAGE_READONLY,PAGE_READWRITE, 
      DWORD flProtect,  
      //文件大小的高32位,一般设置为0,除非文件大于4G 
      DWORD dwMaximumSizeHigh,  
      //文件大小低32位 
      DWORD dwMaximumSizeLow,  
      //映射的名字 
      LPCTSTR lpName  
    ); 2、打开一个映射文件 
    HANDLE OpenFileMapping( 
      //访问数据模式:FILE_MAP_ALL_ACCESS,FILE_MAP_COPY,FILE_MAP_READ,  //FILE_MAP_WRITE 
      DWORD dwDesiredAccess, 
      //子进程是否可以继承 
      BOOL bInheritHandle, 
      //映射文件名 
      LPCTSTR lpName 
    ); 
    3、将映射文件映射到本进程的API函数 
    LPVOID MapViewOfFile(  
      //通过CreateFileMapping或OpenFileMapping返回的文件句柄 
      HANDLE hFileMappingObject,  
      //访问的数据模式:FILE_MAP_WRITE,FILE_MAP_READ,FILE_MAP_ALL_ACCESS 
      DWORD dwDesiredAccess,  
      //指定数据在映射文件中起始位置的高32位 
      DWORD dwFileOffsetHigh,  
      //低32位 
      DWORD dwFileOffsetLow,  
      //需要映射的大小,0表示全部 
      DWORD dwNumberOfBytesToMap  
    ); 
    4、关闭映射的api函数 
    BOOL UnmapViewOfFile(  
      //由MapViewofFile产生的映射文件的地址 
      LPCVOID lpBaseAddress  
    ); 
    5、下面例子中还会用到的几个api函数 创建互斥对象 
    HANDLE WINAPI CreateMutex( 
      LPSECURITY_ATTRIBUTES lpMutexAttributes, 
      BOOL bInitialOwner, 
      LPCTSTR lpName 
    ); DWORD WaitForSingleObject(  
      HANDLE hHandle,  
      DWORD dwMilliseconds  
    );   
      

  7.   

    用DLL:
    library Project1;
    uses
    shareMem,
    windows,
    SysUtils,
    Classes;
    const
     MFileName: Pchar = ’ShareData’; 
     //定义一个记录类型,你所需要共享的数据就保存在这里。
     //当在进程中调用GetDllData时,进程中也应该定义一个与这个一样的记录类型。
    type
     PGlobalDllData = ^TGlobalDllData;
     TGlobalDllData = record
     s: string[50];
     i: integer;
    end;var
     GlobalData: PGlobalDllData; //这是一个全局变量,指向创建的内存映射文件。
     MapHandle: THandle;
     //给外部进程调用的过程,当外部进程调用这个过程后,形参AGlobalData就指向了我//们创建的内存映射文件. 我们可以创建两个进程, 同时调用这个过程, 那么在其中一个进 //程中修改数据后, 在另外一个进程中既可反应出来, 实现了我们需要的共享.procedure GetDllData(var AGlobalData: PGlobalDllData);stdcall; begin
     AGlobalData := GlobalData;
    end;procedure OpenThisData;
    var
     size: integer;
    begin
     size := sizeof(TGlobalDllData);
     //创建一个内存文件映射对象,MfileName保存的值就是该对象的名字。
     mapHandle := CreateFileMapping(Dword(-1), nil, page_readWrite, 0, size, MFileName); if mapHandle = 0 then
      RaiseLastWin32Error;
      //把文件的视图映射到调用进程的地址空间,该函数的返回值就是该对象的首地址。注//意,这是调用进程的地址,两个应用程序调用该DLL,返回值是不一样的。
     GlobalData := MapViewOfFile(mapHandle, File_map_all_Access, 0, 0, size); Globaldata^.s := ’TEST’;
     GlobalData^.i := 5;
     if GlobalData = nil then
     begin
      CloseHandle(MapHandle);
      RaiseLastWin32Error;
     end;
    end;
    //DLL从进程中分离出来时,应该释放相应的空间
    procedure CloseThisData;
    begin
     unmapViewOfFile(GlobalData);
     closeHandle(MapHandle);
    end;procedure DllEntryPoint(dwReason: DWord);
    begin
     case dwReason of
      Dll_Process_Attach: OpenThisData; //调用DLL时传入的参数,由系统自动传入 
      Dll_Process_Detach: CloseThisData; //释放DLL时传入的参数,系统自动传入。
     end;
    end;{$R *.res}exports
     GetDllData; //外部应用程序调用的就是这个过程。
     
    begin
     DllProc := @DllEntryPoint; //该变量是一个全局变量,由它来指定DLL的入口及出 //口函数。
     DllEntryPoint(Dll_Process_Attach);
    end.
      

  8.   

    http://msdn.microsoft.com/en-us/library/aa366551(v=VS.85).aspx