2012-06-19 79 views
0

并不是说它特别有用,但我很好奇为什么以下工作,是因为页面仍然恰好在内存中,即使在文件被删除后?在这种情况下,如果页面被换出,数据将会丢失?FILE_FLAG_DELETE_ON_CLOSE和内存映射文件

#include <iostream> 
#include <memory> 
#include <windows.h> 

int main() 
{ 
    typedef std::unique_ptr<void, decltype(&CloseHandle)> Handle; 
    typedef std::unique_ptr<void, decltype(&UnmapViewOfFile)> View; 

    View v(nullptr, UnmapViewOfFile); 

    { 
     Handle h(CreateFile(
      L"test", 
      GENERIC_READ | GENERIC_WRITE, 
      0, 
      nullptr, 
      CREATE_ALWAYS, 
      FILE_FLAG_DELETE_ON_CLOSE, 
      nullptr 
     ), CloseHandle); 

     // write something so CreateFileMapping succeeds 
     DWORD sz; 
     WriteFile(h.get(), "hello world", 12, &sz, nullptr); 

     Handle m(CreateFileMapping(
      h.get(), 
      nullptr, 
      PAGE_READWRITE, 
      0, 0, 
      nullptr 
     ), CloseHandle); 

     v.reset(MapViewOfFile(
      m.get(), 
      FILE_MAP_WRITE, 
      0, 0, 
      0 
     )); 

     char c; 
     std::cin >> c; // File is still in folder 
    } 

    char c; 
    std::cin >> c; // No file! 

    std::cout << static_cast<char*>(v.get()); // Still writes 
} 

回答

3

FILE_FLAG_DELETE_ON_CLOSE如下指取消链接操作“删除”不幸的Windows传统。事实上,该标志只会导致该文件在关闭文件时与指定的目录断开链接。

与其他操作系统一样,Windows仅使普通用户代码能够从特定目录中取消链接文件。删除始终是操作系统的决定,发生在不能再以任何方式引用文件时。

如果你看,你会发现文件实际上已经从目录中断开,但它实际上不会被删除(以及数据在磁盘上可用于重用的空间),直到其引用计数下降归零。该映射有一个参考。

+0

这是完全正确的,但我想知道为什么你说“不幸”和“Windows传统”。它的缺点与Posix下完全相同,很多程序都依赖于它(PID文件就是一个例子,您可以依赖这个确切的行为)。 – Damon

+0

@Damon:不幸的是,Windows使用术语“删除”,因为它会导致混淆。如果他们称之为“FILE_FLAG_UNLINK_ON_CLOSE”,那就不会有混乱。是的,幸运的是,Windows真的确实做到了这一点,只给普通用户代码访问非链接功能,并且只在引用计数下降到零时实际删除。 –