2

我有一个 Java 程序,它需要监视目录树的变化。我有使用ReadDirectoryChangesW(). 目录打开方式如下:

HANDLE dirHandle = CreateFile(
    path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
    OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
);

然后我dirHandle传给ReadDirectoryChangesW(). 所有这些都很好。

问题是代码的其他部分(在 Java 端)用于File.setLastModified()“触摸”文件或目录(将它们的时间戳更新为“现在”)。这通常有效;但是,当它尝试“触摸”使用CreateFile().

为了查看实际发生的 Windows 错误,我查看了 JDK 源代码,File.setLastModified()并在我自己的代码中重新实现了它,并添加了从GetLastError();打印错误。错误是:

ERROR_SHARING_VIOLATION (error 32)
"The process cannot access the file because it is being used by another process."

怎么回事?这是相同的过程。我什至通过FILE_SHARE_READFILE_SHARE_WRITECreateFile()

有没有办法使这项工作?

更多信息

File.setLastModified()JDK 中的本机代码实现执行以下操作:

h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);

如果我将第一个更改0FILE_SHARE_READ | FILE_SHARE_WRITE,则一切正常。所以看起来JDK实现有点坏了。:(

所以我现在的问题变成了:有没有办法让这项工作而不必使用我自己的(重新)实现File.setLastModified()

4

1 回答 1

1

尽管在这种情况下错误消息有点误导,但您看到的是正常行为。

通过打开dwShareMode设置为零的目录,JDK 实际上要求独占访问,这将导致任何其他访问尝试失败并出现共享冲突错误。这同样适用于来自其他进程和来自您自己的进程的访问。

CreateFile文档描述了参数dwShareMode

如果此参数为零且 CreateFile 成功,则无法共享文件或设备,并且在关闭文件或设备的句柄之前无法再次打开。

您不能请求与具有打开句柄的现有请求中指定的访问模式冲突的共享模式。CreateFile会失败,GetLastError函数会返回ERROR_SHARING_VIOLATION

因此,您似乎已经回答了自己的问题:您需要一个自定义setLastModified函数来指定FILE_SHARE_READ | FILE_SHARE_WRITE访问目录的时间。

于 2009-07-18T10:51:33.090 回答