说,如果我有一个大文件,我会映射到我的进程的虚拟地址空间:
//Error handling is omitted for brevity
HANDLE hFile = CreateFile(L"path-to\\file",
GENERIC_READ,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
char* pAddress = (char*)MapViewOfFile(hFileMapping,
FILE_MAP_READ, 0, 0, 0);
//And get the data
char data_byte = pAddress[offset];
//Then remember to do the cleanup ....
内核虚拟内存管理器何时从磁盘上的文件中读取实际数据(或执行I / O操作以从硬盘驱动器中获取数据):
A)调用MapViewOfFile
或
B)当我使用pAddress[offset]
?
如果上面的答案是B,那么第二个问题是 - 当它获取数据时:
C)是否读取整个文件,或
D)只有包含页面(4K大小,左右)?
答案 0 :(得分:3)
B 和 D
当您为视图调用'<a class="button" href="{}?product_id={}">Reorder</a>',
...
reverse('admin:inventory_reorder_add'), obj.pk
(MapViewOfFile
)内核保留范围虚拟但未将其与实际物理页面关联时(因此不会在开始时分配物理页面)。当您第一次访问部分视图中的某个地址时 - 因为它尚未与物理页面关联(PTE无效) - cpu将生成异常。系统处理此异常时,它会分配已经存在的物理页面,将虚拟地址与此页面关联,从文件中读取数据(如果由文件支持),并从指令继续执行,从而生成异常。
因此,当您将数据映射到内存中时,系统不仅仅是从文件中读取数据,而是等到您第一次访问它时。并且在第一次访问时 - 它读取数据而不是整个部分范围(部分可以不是从文件开始和结束而不是在文件结束)但只有访问页面(可能是几页)