2013-03-07 69 views
0

我正在开发一个程序,需要将大量数据写入磁盘,然后稍后回读少量数据。它需要将相关的数据“分类”在一起,然后一旦找出如何处理它,那么它可以进一步处理数据。它基本上就像一个数据库,但在磁盘上有临时文件。临时文件的部分被相当频繁地重用,因为我在读取它之后并不关心磁盘上的数据,因此文件的一部分可以被回收。我使用I/O完成端口来实现这一点,因为顺序I/O太慢了。I/O完成端口默默无法完全读取

问题是,有时当我读取数据时,我并没有全部收回。例如,我会将读取缓冲区置零,执行20字节的读取操作,并且当相应的完成事件触发时,我的一些读取缓冲区中的一些或甚至都不匹配磁盘上的内容,但所有内容将不会被清零。偶尔,我可以检测到这一点,并尝试睡5秒钟,再次读取相同的部分,它与我第一次尝试阅读的内容相符。这发生在SSD的顶端,所以5秒钟应该足够多以刷新到磁盘。但是,当我停止应用程序并查看文件的内容时,它在磁盘上是正确的。就好像之前的写入没有刷新到磁盘,它试图读取旧数据。

为了测试这个理论,我试着在读取它们时在整个部分写入0xFF。当这个错误再次发生时,我的读缓冲区没有包含0xFFs,就像我预料的那样。所以可以推测,我不是在读旧数据。

我也检查过,以确保从完成事件返回的字节数与我传递给ReadFile的字节数匹配,并且它们匹配。完成事件或ReadFile(ERROR_IO_PENDING除外)不会返回任何错误。我正在使用FILE_ATTRIBUTE_NORMAL,FILE_FLAG_OVERLAPPED和FILE_FLAG_RANDOM_ACCESS创建我的临时文件。

我也试过在尝试阅读之前等待文件给定部分的所有待处理写入完成,但无济于事。我希望Windows能为我做到这一点,但我没有阅读过任何文档。

我真的很茫然,为什么我得到什么看起来部分或损坏的读取。我真的只是寻找一些可能导致这种行为的想法,因为我全力以赴。

回答

0

从你发出的东西的声音开始写入和读取到同一文件的相同部分,有时候读取返回的数据不是你以前写的。

我假设您在发出对文件同一区域的读请求之前正在等待一段数据的写入完成?如果不能在写入完成之前发生读取?当大量的数据被写入到同一磁盘的写入的完成可能开始放缓,写入可能花更多的时间待定(注意,这消耗的资源!)

个人而言,我想包括我自己的内存缓存在写入完成之前知道数据块的层 - 然后,如果写入尚未完成,则可以满足从缓存中读取该部分文件的读取。

+0

我认为我太信任Windows了。根据我以前的测试,我认为windows不会让你读取有待写入的磁盘部分。我用几百个小小的非序列写入来猛击我的硬盘,然后尝试阅读我写过的最后几节。直到全部或几乎所有的写入操作完成(读取最初排队后10秒以上),读取才会完成。现在我认为这是不正确的假设。 – 2013-03-14 15:07:57

+0

此外,我认为这足以计算写入完成的字节数,以确定是否可以从给定的文件部分读取。这似乎并不准确,因为写入可能无序完成。现在,我正在等待具体的写作完成,然后尝试阅读,到目前为止,似乎解决了我的问题。 – 2013-03-14 15:15:36

+0

这两个观察结果都没有让我吃惊。很高兴你解决了你的假设。 – 2013-03-18 15:56:38