FileMapping 和 Istream Binary 之间的区别
Difference Between FileMapping and Istream Binary
我有两个代码示例,第一个如下:
//THIS CODE READS IN THE CALC.EXE BINARY INTO MEMORY BUFFER USING ISTREAM
ifstream in("notepad.exe", std::ios::binary | std::ios::ate);
int size = in.tellg();
char* buffer = new char[size];
ifstream input("calc.exe", std::ios::binary);
input.read(buffer, size);
这是第二个:
//THIS CODE GETS FILE MAPPING IMAGE OF SAME BINARY
handle = CreateFile("notepad.exe", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
mappinghandle = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
image = (DWORD) MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
我的问题是,这两种方法到底有什么区别?如果我们忽略文件映射更好地处理的大小问题,这两个返回的对象是否本质上相同? image
变量不会指向与 buffer
变量本质上相同的东西——这是内存中二进制可执行文件的映像吗?两者有什么区别?
当调用input.read() 而MapViewOfFile 不访问文件数据时,使用std::ifstream 的方法实际上将文件的数据复制到RAM 中。
MapViewOfFile() returns一个指针,但只有当你访问指针指向的虚拟内存时,数据才会真正从磁盘中读取。
// This creates just a "view" of the file but doesn't read data from the file.
const char *buffer = reinterpret_cast<const char*>( MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0) );
// Only at this point the file actually gets read. The virtual memory manager now
// reads a page of 4KiB into memory.
char value = buffer[ 10 ];
为了进一步说明差异,假设我们从 memory-mapped 文件中读取偏移量 12345 处的一个字节:
char value = buffer[ 12345 ];
现在虚拟内存管理器不会读取到此偏移量的所有数据,而是只会将最接近该偏移量的页面映射到内存中。那将是位于偏移量 12288 (=4096*3) 和 16384 (=4096*4) 之间的页面。
第一个从文件读入缓冲区,缓冲区独立于原始文件。
第二个是访问文件本身,当映射存在时您将无法删除文件,虽然您不能进行更改,因为您有 read-only 映射,但已进行更改在你的映射中可以看到你程序之外的那个文件。
我有两个代码示例,第一个如下:
//THIS CODE READS IN THE CALC.EXE BINARY INTO MEMORY BUFFER USING ISTREAM
ifstream in("notepad.exe", std::ios::binary | std::ios::ate);
int size = in.tellg();
char* buffer = new char[size];
ifstream input("calc.exe", std::ios::binary);
input.read(buffer, size);
这是第二个:
//THIS CODE GETS FILE MAPPING IMAGE OF SAME BINARY
handle = CreateFile("notepad.exe", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
mappinghandle = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
image = (DWORD) MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
我的问题是,这两种方法到底有什么区别?如果我们忽略文件映射更好地处理的大小问题,这两个返回的对象是否本质上相同? image
变量不会指向与 buffer
变量本质上相同的东西——这是内存中二进制可执行文件的映像吗?两者有什么区别?
当调用input.read() 而MapViewOfFile 不访问文件数据时,使用std::ifstream 的方法实际上将文件的数据复制到RAM 中。
MapViewOfFile() returns一个指针,但只有当你访问指针指向的虚拟内存时,数据才会真正从磁盘中读取。
// This creates just a "view" of the file but doesn't read data from the file.
const char *buffer = reinterpret_cast<const char*>( MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0) );
// Only at this point the file actually gets read. The virtual memory manager now
// reads a page of 4KiB into memory.
char value = buffer[ 10 ];
为了进一步说明差异,假设我们从 memory-mapped 文件中读取偏移量 12345 处的一个字节:
char value = buffer[ 12345 ];
现在虚拟内存管理器不会读取到此偏移量的所有数据,而是只会将最接近该偏移量的页面映射到内存中。那将是位于偏移量 12288 (=4096*3) 和 16384 (=4096*4) 之间的页面。
第一个从文件读入缓冲区,缓冲区独立于原始文件。
第二个是访问文件本身,当映射存在时您将无法删除文件,虽然您不能进行更改,因为您有 read-only 映射,但已进行更改在你的映射中可以看到你程序之外的那个文件。