【问题标题】:Setting the last-modified-time of a directory opened for ReadDirectoryChangesW设置为 ReadDirectoryChangesW 打开的目录的最后修改时间
【发布时间】:2009-07-17 17:21:40
【问题描述】:

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

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 错误,我查看了 File.setLastModified() 的 JDK 源代码,并在我自己的代码中重新实现了它,并添加了来自 GetLastError() 的打印错误;错误是:

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

WTF?这是相同的过程。我什至将FILE_SHARE_READFILE_SHARE_WRITE 传递给CreateFile()

有没有办法让它工作?

更多信息

JDK中File.setLastModified()的原生代码实现做了一个:

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

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

所以我现在的问题变成了:有没有一种方法可以在不必使用我自己的(重新)实现 File.setLastModified() 的情况下完成这项工作?

【问题讨论】:

    标签: java windows winapi createfile readdirectorychangesw


    【解决方案1】:

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

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

    CreateFile documentation 描述了dwShareMode 参数:

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

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

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

    【讨论】:

    • 是的,购买 为什么JDK要求独占访问?在这种情况下似乎没有必要。
    猜你喜欢
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 2011-11-11
    • 2016-04-03
    • 2012-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多