FlushViewOfFile() 原型如下:
[C++] 纯文本查看 复制代码 BOOL WINAPI FlushViewOfFile(
__in LPCVOID lpBaseAddress,
__in SIZE_T dwNumberOfBytesToFlush
);
该函数将视图中的文件数据写入到磁盘。调用该函数后,对映射视图的内存操作会写回到磁盘上的文件中。
第 1 个参数 lpBaseAddress 是需要写入到文件的数据的起始位置。
第 2 个参数 dwNumberOfBytesToFlush 是写入的字节数,如果改值为 0 ,那么将整个视图都写回。
如果函数返回值是非零值那么表示执行成功,否则失败。
注意,即使不调用该函数,数据最终也会写回到磁盘,但调用该函数,一般情况下,数据会立刻写回到磁盘。
测试代码:
[C++] 纯文本查看 复制代码
#include "stdafx.h"
#define FILE_MAP_START 0x28804 //文件映射起始位置
#define BUFSIZE 1024 // 内存大小
typedef struct {
int i;
int b;
}are;
int _tmain(int argc, _TCHAR* argv[])
{
setlocale (LC_ALL, "CHS");
HANDLE hMapFile; // 文件内存映射区域的句柄
HANDLE hFile; // 文件的句柄
DWORD dBtyesWritten; // 写入的字节数
DWORD dwFileSize; // 文件大小
DWORD dwFileMapSize; // 文件映射的大小
DWORD dwMapViewSize; // 视图(View)大小
DWORD dwFileMapStart; // 文件映射视图起始位置
DWORD dwSysGran; // 系统内存分配粒度
SYSTEM_INFO SysInfo; // 系统信息
LPVOID lpMapAddress; // 内存映射区域起始位置
PCHAR pData; // 数据
INT i; // 循环变量
INT iData;
INT iViewDelta;
//创建一个文件
hFile = CreateFile (argv[1], GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf ("Create file error\n");
return (-1);
}
//依次写入整数,一共 65535 个,共 65535*4 个字节
for (i = 0; i < 65535; i++)
WriteFile (hFile, &i, sizeof(i), &dBtyesWritten, NULL);
//检查写入后文件的大小
dwFileSize = GetFileSize (hFile, NULL);
_tprintf (TEXT("文件大小:%d\n"), dwFileSize);
/* 获取系统信息,内存分配粒度(64K)
* 下面几个计算是为了映射的数据与系统内存分配粒度对其,提高内存访问效率
*/
GetSystemInfo (&SysInfo);
dwSysGran = SysInfo.dwAllocationGranularity; //内存分配粒度,一般为 64KB
//计算 mapping 起始位置
dwFileMapStart = (FILE_MAP_START / dwSysGran) * dwSysGran;
dwMapViewSize = (FILE_MAP_START % dwSysGran) + BUFSIZE; //mapping view 大小
dwFileMapSize = FILE_MAP_START + BUFSIZE; // mapping 的大小
iViewDelta = FILE_MAP_START - dwFileMapStart; // 需要读取的数据的便宜
hMapFile = CreateFileMapping ( hFile, // 需要映射的文件句柄
NULL, // 使用默认安全选项
PAGE_READWRITE, // 可读,可写
0, // mapping 对象的大小,高位
dwFileMapSize, // mapping 对象的大小,低位
NULL);
if (hMapFile == NULL) {
printf ("CreateFileMapping error : %d\n", GetLastError());
return (-2);
}
// 映射 view
lpMapAddress = MapViewOfFile ( hMapFile, // mapping 对象的句柄
FILE_MAP_ALL_ACCESS, // 可读,可写
0, // 映射的文件偏移,高位
dwFileMapStart, // 映射的文件偏移,低位
dwMapViewSize); // 映射到 View 的文件大小
_tprintf (TEXT("文件视图(map view)相对于文件的起始位置:0x%x\n"), dwFileMapStart);
_tprintf (TEXT("文件视图(map view)的大小:0x%x\n"), dwMapViewSize);
_tprintf (TEXT("文件映射对象的大小:0x%x\n"), dwFileMapSize);
_tprintf (TEXT("从相对于文件视图(map view)的 0x%x 字节处读取数据为:"), iViewDelta);
pData = (PCHAR)lpMapAddress + iViewDelta; //设置指针
iData = *(PINT)pData; //读取一个数据
_tprintf (TEXT("0x%.8x\n"), iData);
_tprintf (TEXT("从视图起始的 32 个字节是:\n"));
for (i = 1; i <= 32; i++) {
printf ("0x%.2x ", *((unsigned char *)lpMapAddress + i - 1));
if (i % 16 == 0)
printf ("\n");
}
FillMemory(lpMapAddress, 32, (BYTE)0xff);
//将数据写回到硬盘上
FlushViewOfFile (lpMapAddress, dwMapViewSize);
//FlushFileBuffers(hFile);
CloseHandle (hMapFile);
CloseHandle (hFile);
return 0;
}
在将数据写回到硬盘前,先观察一下从文件偏移地址 0x20000 开始的 32 个字节数据,如下图所示:
执行程序后比较一下发现数据已经写入:
|