FileMapping和Istream二进制文件之间的区别

时间:2017-02-20 23:44:41

标签: c++ istream

我有两个代码示例,第一个是以下内容:

//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变量基本相同的东西 - 这是内存中二进制可执行文件的图像吗?这两者之间有什么区别?

2 个答案:

答案 0 :(得分:1)

当调用input.read()而MapViewOfFile不访问文件数据时,使用std :: ifstream的方法实际上将文件的数据复制到RAM中。

MapViewOfFile()返回一个指针,但是当您访问指针指向的虚拟内存时,实际上只会从磁盘读取数据。

// 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 ];

为了进一步说明差异,我们从内存映射文件中读取偏移量为12345的字节:

char value = buffer[ 12345 ];

现在虚拟内存管理器不会读取到此偏移量的所有数据,而只是将最接近该偏移量的页面映射到内存中。那将是位于偏移12288(= 4096 * 3)和16384(= 4096 * 4)之间的页面。

答案 1 :(得分:0)

第一个从文件读入缓冲区,缓冲区独立于原始文件。

第二个是访问文件本身,当映射存在时您将无法删除该文件,虽然由于您具有只读映射而无法进行更改,但是对该文件进行了更改您的程序可以在您的映射中看到。