c++ - FileMapping 和 Istream Binary 之间的区别

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

最佳答案

当调用 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) 之间的页面。

关于c++ - FileMapping 和 Istream Binary 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42356171/

相关文章:

c++ - 对 "av_new_packet"的 undefined reference (使用 Qt)

c++ - 抽象类中 protected 成员变量?

c++ - 在吃 EOF 后重用 std::cin

c++ - 找到 cin 和 ifstream 的流结尾?

c++ - Bithacking 比较(较少)运算符

C++:多态类模板

c++ - Lotus Notes C++ API 通过 UNID 获取文档

c++ - 为什么 std::getline() 在格式化提取后跳过输入?

C++:使用 std::cin 的多个拷贝?

c++ - 从流输入到枚举类型