我有一个假设的场景,其中一个文件句柄在异步模式下打开,一些线程附加到该文件句柄。通过将Offset
结构的OffsetHigh
和OVERLAPPED
部分设置为0xFFFFFFFF
来追加它们,如MSDN article for WriteFile
中所述。
我可以在第一个附加完成之前以这样的附加模式发出第二次写入,并期望该文件包含第一个附加的全部内容,后跟第二个附加的全部内容吗?或者我必须等待发出以下异步写入,直到上一次写入完成?
答案 0 :(得分:0)
是。有用。我在一家使用类似方案的公司工作,虽然每次都要求他们的搜索工作,预定义的文件已知大小(约2Gb ......)然后在最后截断文件。
但是,您可以通过在每次写入之前前往正确的位置来“追加”。你必须自己处理这个职位。
并且每个线程也必须以原子方式访问文件,“当然。”
一个简单的例子:
lock mutex
seek to position
write data
position += data size
unlock mutex
当然,我假设在从任何线程调用此函数之前,文件已正确打开。
除非你先创建一个大文件(由于虚拟地创建了全零的文件,这是非常快的),否则你不能做的一件事就是根据诸如帧号之类的东西来寻找位置。因此,如果线程3想要以“size * 3”写入并且在线程2写入“size * 2”之前发生,则seek()将失败...
答案 1 :(得分:0)
即使从单个线程,也不应发出偏移设置为 0xFFFFFFFF 的多个未完成的 WriteFile 操作。这将导致多个调用同时尝试访问数据末尾并导致数据损坏的问题。这是因为如果 WriteFile 在异步模式下运行,并且在使用文件末尾的进程中还有其他未完成的 WriteFile ,则某些操作可能会将数据写入结尾文件和其他未完成的操作将得到错误的文件结束指针。简而言之,您应该只使用 0xFFFFFFFF 一次并等待操作完成以使用该偏移发出另一个操作。否则,您需要自己计算偏移量,以便每个未完成的写入操作使用唯一的偏移量。由于关于该偏移量的MSDN文档很差,这个错误花了我3天才找到。