Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写文件,然后将其读回以验证其内容,确保您';我们得到了什么';它在磁盘上,而不是缓存上_C++_Windows_Winapi_Mfc_Filesystems - Fatal编程技术网

C++ 如何编写文件,然后将其读回以验证其内容,确保您';我们得到了什么';它在磁盘上,而不是缓存上

C++ 如何编写文件,然后将其读回以验证其内容,确保您';我们得到了什么';它在磁盘上,而不是缓存上,c++,windows,winapi,mfc,filesystems,C++,Windows,Winapi,Mfc,Filesystems,我在Windows上使用本机/C++/Win32/MFC代码通过MFC序列化保存文档文件。在编写过程中,我插入了自己的CFile派生类,使我能够在编写数据时访问数据。这允许我在数据输出到文件时计算数据的校验和(或哈希等) 保存文件后,我希望允许验证文件的选项。这样做的想法是重新打开文件,并通过验证校验和/散列等来读取它 不过,我想知道,是否有可能在刚写完文件后,当我马上读回文件时,操作系统会给我未写的数据。在这种情况下,测试并没有真正告诉我文件在磁盘上看起来很好 我的担心是正确的吗?如果是这样,

我在Windows上使用本机/C++/Win32/MFC代码通过MFC序列化保存文档文件。在编写过程中,我插入了自己的CFile派生类,使我能够在编写数据时访问数据。这允许我在数据输出到文件时计算数据的校验和(或哈希等)

保存文件后,我希望允许验证文件的选项。这样做的想法是重新打开文件,并通过验证校验和/散列等来读取它

不过,我想知道,是否有可能在刚写完文件后,当我马上读回文件时,操作系统会给我未写的数据。在这种情况下,测试并没有真正告诉我文件在磁盘上看起来很好


我的担心是正确的吗?如果是这样,有没有办法避免此问题?

如果您使用的是CFile,您可以调用以确保所有内容都写入磁盘。根据文件

virtual void Flush( );
强制将文件缓冲区中剩余的任何数据写入文件


我不知道这个问题的答案。不过,我知道该去哪里找

保证数据被安全地写入磁盘,无论发生什么情况——甚至是电源故障。他们一定在做你需要的事情,他们的代码是开源的,并且有漂亮的注释

SQLite中单个事务中的所有更改 完全或根本没有,即使将更改写入 磁盘被中断

程序崩溃

操作系统崩溃

或者是停电

上一段的声明在SQLite中进行了广泛的检查 回归测试套件,使用模拟 操作系统崩溃和断电对数据库文件的影响 失败


如果确实要这样做,则可以通过指定和/或在打开文件时避免磁盘缓存和缓冲。注意使用这些选项会使事情复杂化

正在打开文件或设备时,没有用于数据读取和写入的系统缓存。此标志不影响硬盘缓存或内存映射文件。 使用文件\u标志\u无缓冲标志成功使用CreateFile打开的文件有严格的要求,有关详细信息,请参阅


一个更简单的替代方法是在关闭文件句柄之前调用。

我的猜测是,与所有其他文件抽象一样,这只是将程序的缓存刷新到操作系统。无法保证这会实际刷新到磁盘。@edA-qamort-ora-y但如果您使用另一个操作系统调用再次读取数据,它将是正确的regardless@Nerdtron只需刷新缓冲区。我的理解是Windows最终会告诉磁盘驱动程序将缓冲区刷新到磁盘。如果磁盘驱动程序不能做到这一点(“性能优化”),那么您对此无能为力。我手头没有,但我相信SQLServer的PSS有几篇博客文章提到这个问题是导致日志文件损坏的主要原因。但基本上:告诉Windows刷新文件,它应该刷新文件。除非磁盘驱动程序对其撒谎,否则Windows或您无法检测到这种情况。@Nerdtron我在MSDN上找不到任何保证文件关闭时将被刷新的文档,但请注意-您说您来自
CFile
,因此可能会将
Close
重写为
Flush(); CFile::Close()
?@Nerdtron我已经有一段时间没有输入MFC源代码了,但是您可以进入CFile::Close和CFile::~CFile,看看是否为您完成了刷新有趣的,谢谢您的提示!我来看看他们的代码。SQLite不能保证这一点,因为这是不可能的。除非有人发明了无电源运行的磁盘@David Heffernan请阅读SQLITE保证,我已经在我的回答中发布了该保证。该保证不是你在回答中所说的。您说过即使断电,数据也会写入磁盘。@ravenpoint我相信这是因为SQLite在每个数据库中都有一个小日志,这是操作系统外部的一种机制。请注意,保证不是数据完全写入或根本不写入,而是更改完全写入或根本不写入。如果电源故障中断了提交,文件中仍然会有垃圾漂浮,但日志知道这一点。写入文件。关上把手。用无用的缓冲器填充闸板,以强制冲洗。删除缓冲区。读取文件。(如果计算机的RAM大于虚拟进程空间,则无法工作)@Ambeco更重要的是,它将对计算机上的任何其他进程产生可怕的影响。我不认为我想在这个进程中填充RAM。