即使使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建文件,文件也会留在磁盘上
Posted
技术标签:
【中文标题】即使使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建文件,文件也会留在磁盘上【英文标题】:Files are left on disk even if created with FILE_FLAG_DELETE_ON_CLOSE attribute 【发布时间】:2020-05-27 11:43:16 【问题描述】:我有一个程序可以创建具有 FILE_FLAG_DELETE_ON_CLOSE 属性的文件。我在某些机器上看到了极少数情况,即使进程停止,文件仍然存在。
CreateFile(fileName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_ALWAYS,
FILE_FLAG_DELETE_ON_CLOSE,
NULL);
注意:我确信 100% 没有其他进程拥有这些文件的句柄。此外,所有句柄(OpenFile、CreateFile)都是使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建的。
我正在尝试找到在所有句柄关闭后立即删除文件的保证不起作用的边缘情况。(操作系统意外关闭除外) 有谁知道文件可以留在磁盘上的其他情况?
【问题讨论】:
如果您没有明确关闭句柄(使用CloseHandle()
),那么您应该 - 并检查返回状态。如果你没有明确地这样做,那么一些异常的进程终止可能会导致文件句柄没有被关闭(例如,使用TerminateProcess()
终止的进程)。此外,“正常”终止的进程可能需要一段时间才能关闭,并且您尚未明确关闭的任何句柄将在此之前保持打开状态。
无法保证在文件的所有句柄都已关闭后会“立即”删除该文件。此时,该文件被标记删除,这将在之后的任何时候发生。 @pet 如果进程终止,无论如何,操作系统将关闭其所有打开的句柄。
看,我明确地关闭了句柄,这不是重点。关键是要了解为什么操作系统可以忽略 FILE_FLAG_DELETE_ON_CLOSE 属性。在什么情况下会发生?不幸的是,这种情况很少见,所以我无法理解此时服务器上发生了什么导致文件未被删除。
@Svirin "关键是要理解为什么操作系统可以忽略 FILE_FLAG_DELETE_ON_CLOSE 属性" - 它不会忽略该标志。但是,您所描述的通常只有在文件有打开的句柄时才会发生。您是否使用Process Explorer 之类的工具验证?
@Svirin 在正常情况下,这个问题不会发生。即使在文件打开并且进程具有其句柄时关闭,该文件仍然被系统删除(系统终止进程导致所有文件的句柄都关闭)。所以这个问题可能会在一些罕见的异常情况下发生,例如当系统没有时间做清理工作时突然断电等。
【参考方案1】:
正如 cmets 所说,很可能仍然在文件上打开了一个句柄。但是,这不一定是它仍然存在的唯一原因。
您可能有一个名为WriteFile
的程序已被强制终止(因此句柄已关闭),并且挂起的 IRP 正在保存该文件。这个 IRP 不允许文件被释放,直到它的引用计数在内核中达到 0。因为 IRP 仍处于挂起状态,所以它是非零值。
【讨论】:
IRP 是什么意思? @MarkRansom IRP 是一个 I/O 请求数据包。它是有关 I/O 操作的信息,通常由 Windows 内核的 IO 子系统发送给驱动程序。待处理的 IRP 是驱动程序尚未完全处理的 IRP,不应释放其资源(文件)。以上是关于即使使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建文件,文件也会留在磁盘上的主要内容,如果未能解决你的问题,请参考以下文章
即使我在 POST 上收到 200 响应,$_POST 数据还是空的?
即使使用 `-dec-math`,gfortran 也会对 `dacosd_` 给出未定义的引用
Alt 通量操作:即使调用 this.generateActions,_this.actions 也未定义
为什么即使使用异步流,cudaMemcpyAsync和内核启动也会阻塞?
即使添加了“如果 __name__ == '__main__':”,Windows 上的 python joblib Parallel 也无法正常工作