Windows I/O完成端口无法完全读取

Windows I/O完成端口无法完全读取,windows,file-io,io-completion-ports,Windows,File Io,Io Completion Ports,我正在开发一个程序,需要将大量数据写入磁盘,然后稍后再读回少得多的数据。它需要将相关数据“装箱”在一起,然后一旦确定如何处理这些数据,就可以进一步处理这些数据。它基本上就像一个数据库,但磁盘上有临时文件。temp文件的一部分被相当频繁地重复使用,因为我不关心磁盘上的数据,在我将其读回后,所以该部分文件可以被回收。我使用I/O完成端口来实现这一点,因为顺序I/O太慢了 问题是,有时当我读取数据时,我无法将所有数据都取回。例如,我将清空我的读缓冲区,执行一个20字节的读操作,当相应的完成事件触发时,

我正在开发一个程序,需要将大量数据写入磁盘,然后稍后再读回少得多的数据。它需要将相关数据“装箱”在一起,然后一旦确定如何处理这些数据,就可以进一步处理这些数据。它基本上就像一个数据库,但磁盘上有临时文件。temp文件的一部分被相当频繁地重复使用,因为我不关心磁盘上的数据,在我将其读回后,所以该部分文件可以被回收。我使用I/O完成端口来实现这一点,因为顺序I/O太慢了

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

为了验证这一理论,我在阅读时尝试在整个部分上写0xFF。当这个错误再次发生时,我的读取缓冲区没有像我预期的那样包含0xFFs。所以我想我不是在读旧数据

我还检查以确保完成事件返回的字节数与我传递给ReadFile的字节数匹配,并且它们确实匹配。完成事件或ReadFile没有返回任何错误(错误IO未决除外)。我正在使用文件属性、文件标志重叠和文件标志随机访问创建临时文件

我还尝试在尝试读取之前等待文件给定部分的所有挂起写入完成,但没有成功。我希望Windows能为我做到这一点,但我读过的任何文档都没有涉及到这一点


我真的很不明白为什么我会得到看起来不完整或损坏的内容。我真的只是在寻找一些可能导致这种行为的想法,因为我已经筋疲力尽了。

从您对同一文件的相同部分进行写入和读取的声音中,有时读取返回的数据与您之前认为的不同

我假设您在对文件的同一区域发出读取请求之前,正在等待一段数据的写入完成?如果没有,则在写入完成之前可能会发生读取?当大量数据写入同一磁盘时,写入完成速度可能会开始减慢,并且写入可能会花费更多的挂起时间(请注意这会消耗资源!)


就我个人而言,我会包括我自己的内存缓存层,它知道数据块,直到写入完成。如果写入尚未完成,您可以满足从缓存中读取这部分文件的要求。

我认为我太信任Windows了。根据我之前的测试,我认为windows不允许您读取磁盘中有挂起写入的部分。我用几百兆的小的、不连续的写操作猛击我的硬盘,然后试着读我写过的最后几节,以此来测试这一点。在所有或几乎所有写入完成之前(读取最初排队后10秒以上),读取永远不会完成。我现在认为这是一个错误的假设。此外,我认为计算写入完成的字节数就足以确定我是否可以从给定的文件部分读取。这似乎也不准确,因为写入可能会无序完成。现在我正在等待具体的写作完成,然后再尝试阅读,到目前为止,这似乎解决了我的问题。这两个观察结果都没有让我感到惊讶。很高兴你修正了你的假设。