使用std :: ifstream而不是文件缓存强制读取磁盘

问题描述:

我有一个程序使用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

你如何修改文件?许多我们认为“修改”文件的东西实际上并不修改文件,而是用新的修改过的文件替换文件。 –

不要认为这是由于某种“缓冲”,我会首先寻找明显的东西。

  • 确定用户正在更改您正在阅读的文件吗?
  • 您确定重新加载数据是否正确地更新您的内存中的数据结构?
  • 你确信DataValid()正在做你想做的吗?

操作系统使用文件缓冲区提高磁盘性能的事实通常在应用程序级别不可见。只要你在看同一个文件,操作系统知道用户更新了文件,如果你重新打开它,那么你会看到更改后的数据。如果数据甚至没有机会刷新到磁盘,这不会影响您的应用程序。

+0

1)那么,用户就是我,只有文件的版本,所以我相信我正在改变文件的好版本。至于其他方面,在成功打开我的文件后,我逐行逐行读入文件,并且看到数据与旧版本文件相似,而不是新版本。我认为这是由于应用程序缓冲所致,如果我重新加载应用程序,它将读取新版本。至于对文件的修改,它是用记事本完成的(并在之后保存)。在应用程序级别遇到这样的问题实际上有点怪异... –

+1

您的应用程序可能是否具有另一个在其他地方打开的文件的句柄?这可能有助于解释为什么重新加载应用程序。当您的应用程序关闭时,您打开的所有*手柄都将关闭。 –

+0

哼哼......那种尴尬......当我看到我的程序的句柄(使用进程管理器)时,我意识到我现在在两个几乎相同的路径中使用了该文件的两个版本(我在升级本地存储库到龟svn到1.7时出错,所以我不得不创建一个新的,并仍在使用第一个存储库的解决方案)。 –