我正在编写一个后台应用程序,通过设置“优化快速删除”策略将文件循环复制到 U 盘。但是,如果通过此过程中途移除内存棒(特别是在下面的 WriteFile() 调用中,它返回错误文件未找到)应用程序挂起,驱动器将永远无法从任何其他应用程序访问并且 PC 无法关闭/注销/重新启动等。所有正在运行的 Windows 资源管理器实例也因此挂起。
我已将问题追溯到移除棒后进行的 CloseHandle() 调用,并发生上述错误。它几乎就像 CloseHandle() 在某个地方无限期地阻塞在驱动程序中,因为棒不再存在?无论如何,如果 WriteFile() 返回 ERROR FILE NOT FOUND,我通过简单地跳过 CloseHandle() 调用设法解决了这个问题。然而,这会导致另一个问题,文件每隔一段时间就会被不可恢复地损坏,修复它的唯一方法是使用 chkdsk,或重新格式化内存棒。
请注意,这只发生在 XP(SP2 和 3)上,Vista 似乎没有遇到此问题。代码片段如下:
HANDLE hFile = CreateFile(szFile,
GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
CREATE_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
if (!WriteFile(hFile, pBuffer, dwBufferSize, &dwWritten))
{
int nLastError = GetLastError();
}
// If usb stick is removed during WriteFile(), ERROR_FILE_NOT_FOUND usually results.
// If handle is closed at this point then drive is inaccessible.
// If CloseHandle() is skipped, then file corruption occurs instead
if (nLastError != ERROR_FILE_NOT_FOUND)
{
CloseHandle(hFile);
}
}
我几乎尝试了 CreateFile() 的所有标志组合,但都无济于事。有没有人以前见过这个或者有什么好主意如何避免这两个问题中的任何一个发生。我看到的是驱动程序问题,它已在 vista 下悄悄修复了吗?
感谢您的帮助。
最佳答案
Its almost as if CloseHandle() is blocking indefinitely in the driver somewhere because the stick is no longer there?
听起来很有道理。 CloseHandle() 最终将发出一个文件系统 IRP,并且您没有使用非阻塞 I/O,因此 IRP 将是同步的,但看起来实际文件系统突然从文件系统驱动程序下面消失了,即IRP 永远不会完成。这意味着你被塞满了 - 导致发出文件系统 IRP 的用户模式函数调用将永远不会返回。
尝试使用非阻塞 I/O - 这很可能会解决这个问题,至少从不挂起的角度来看是这样。您仍然会遇到资源丢失等问题,因为 IRP 仍会被传递并且几乎肯定不会再返回,但至少您不会阻塞它。
顺便说一句,“为快速删除而优化”我想说的是旨在减少缓存的数量,并可能影响写入文件系统的顺序以减少损坏的机会;我非常怀疑它是为了在文件系统离开时保留文件系统 during 写入!
您不必对这会杀死文件系统感到惊讶。
关于c++ - 将文件写入 USB 内存棒会导致意外删除时文件损坏/锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/681221/