2012-06-19 122 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真的確實做到了這一點,只給普通用戶代碼訪問非鏈接功能,並且只在引用計數下降到零時實際刪除。 –