2011-11-01 143 views
0

我有一個程序使用std :: ifstream從文件加載數據並將數據存儲在結構中。之後,我驗證我想要的數據是否在文件中。如果不是,我要求用戶修改文件並按下一個鍵。然後我重新加載文件。問題是,即使用戶修改了文件,我總是會在文件中獲得相同的數據,因爲該文件似乎在應用程序中緩存。我已經看到,在win32 API中,可以使用標誌FILE_FLAG_NO_BUFFERING來避免在讀取文件時使用緩衝副本,但是我希望將該功能與std :: ifstream一起使用。有沒有辦法使用通過win32 API創建的句柄與ifstream或反正強迫它直接在std :: ifstream?使用std :: ifstream而不是文件緩存強制讀取磁盤

這裏有一個 「簡化」 的代碼示例:

SomeStructure s = LoadData(fileName); 
while(!DataValid(s)) 
    s = LoadData(fileName); 


SomeStructure LoadData(const std::string& fileName) 
{ 
    std::ifstream fileStream; 
    while(!OpenFileRead(fileName, fileStream)) 
    { 
     std::cout<<"File not found, please update it"; 
     fileStream.close(); 
     //Wait for use input 
     std::string dummy; 
     std::getline(std::cin, dummy); 
    } 
    //... Read file, fill structure, and return 
    std::string line; 
    while(std::getline(fileStream, line) && line!="") 
    { 
     //At this point, I can see that line is wrong 
     StringArray namedatearray=Utils::String::Split(line, "|"); 
     assert(namedatearray.size()==2); 
     //Add data to my structure (a map) 
    } 
    fileStream.close(); 
    //return structure 
} 

bool OpenFileRead(const std::string& name, std::fstream& file) 
{  
    file.open(name.c_str(), std::ios::in); 
    return !file.fail(); 
} 

感謝。

編輯:當然,這是一個錯誤,因爲我有兩個相同的文件在兩個非常相似的路徑。查看用進程管理器打開的文件句柄(而不是相關的文件路徑讓我發現它)。

+2

無緩衝IO在這裏沒有影響。您要麼有錯誤的寫入代碼,要麼有錯誤的讀取代碼。 – Joe

+2

如果問題在應用程序中緩存,如您聲明的那樣,則無緩衝的I/O不會幫助您,因爲無緩衝的I/O意味着在內核*中不緩衝*。它對應用程序的緩存數據沒有影響。你不可能讓'ifstream'處理一個無緩衝的句柄,因爲[當你創建一個帶有約束的對象時,你必須確保每個使用該對象的人都理解這些約束](http://blogs.msdn。 COM/b/oldnewthing /存檔/ 2010/04/14/9995509.aspx)。 –

+0

你如何修改文件?許多我們認爲「修改」文件的東西實際上並不修改文件,而是用新的修改過的文件替換文件。 –

回答

2

不要認爲這是由於某種「緩衝」,我會首先尋找明顯的東西。

  • 確定用戶正在更改您正在閱讀的文件嗎?
  • 您確定重新加載數據是否正確地更新您的內存中的數據結構?
  • 你確信DataValid()正在做你想做的嗎?

操作系統使用文件緩衝區提高磁盤性能的事實通常在應用程序級別不可見。只要你在看同一個文件,操作系統知道用戶更新了文件,如果你重新打開它,那麼你會看到更改後的數據。如果數據甚至沒有機會刷新到磁盤,這不會影響您的應用程序。

+0

1)那麼,用戶就是我,只有文件的版本,所以我相信我正在改變文件的好版本。至於其他方面,在成功打開我的文件後,我逐行逐行讀入文件,並且看到數據與舊版本文件相似,而不是新版本。我認爲這是由於應用程序緩衝所致,如果我重新加載應用程序,它將讀取新版本。至於對文件的修改,它是用記事本完成的(並在之後保存)。在應用程序級別遇到這樣的問題實際上有點怪異... –

+1

您的應用程序可能是否具有另一個在其他地方打開的文件的句柄?這可能有助於解釋爲什麼重新加載應用程序。當您的應用程序關閉時,您打開的所有*手柄都將關閉。 –

+0

哼哼......那種尷尬......當我看到我的程序的句柄(使用進程管理器)時,我意識到我現在在兩個幾乎相同的路徑中使用了該文件的兩個版本(我在升級本地存儲庫到龜svn到1.7時出錯,所以我不得不創建一個新的,並仍在使用第一個存儲庫的解決方案)。 –