2017-02-20 77 views
1

我有两个代码样本之间,第一个是:差异文件映射和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变量基本相同的东西 - 这是内存中二进制可执行文件的映像?两者之间有什么区别?

+1

那么,你有一段时间在Linux上进行第二次编译...... – user4581301

+0

你应该在第二个例子中添加适当的变量声明。例如, MapViewOfFile返回一个指针,将它转换为DWORD对于访问数据没有任何意义。 – zett42

回答

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

0

第一个从文件读入缓冲区,缓冲区与原始文件无关。

第二个访问文件本身,当存在映射时,您将无法删除该文件,尽管由于您具有只读映射而无法进行更改,因此对该文件所做的更改您的程序外部可以在您的映射中可见。

相关问题