设置为 ReadDirectoryChangesW 打开的目录的上次修改时间
我有一个 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_READ
和 FILE_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()
?
I hava a Java program that needs to monitor a directory tree for changes. I have JNI code that uses ReadDirectoryChangesW()
. The directory is opened like:
HANDLE dirHandle = CreateFile(
path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
);
and then I pass dirHandle
to ReadDirectoryChangesW()
. All of that works just fine.
The problem is that other parts of the code (on the Java side) use File.setLastModified()
to "touch" files or directories (update their timestamps to be "now"). This generally works; however, it fails when it tried to "touch" the directory that was opened using CreateFile()
.
To see what Windows error is actually occurring, I looked at the JDK source for File.setLastModified()
and reimplemented it in my own code with the addition of printing the error from GetLastError()
; the error is:
ERROR_SHARING_VIOLATION (error 32)
"The process cannot access the file because it is being used by another process."
WTF? It's the same process. I even passed FILE_SHARE_READ
and FILE_SHARE_WRITE
to CreateFile()
.
Is there a way to make this work?
More Info
The native code implementation of File.setLastModified()
in the JDK does a:
h = CreateFileW(pathbuf, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
If I change the first 0
to FILE_SHARE_READ | FILE_SHARE_WRITE
, it all works. So it seems that the JDK implementation is a little broken. :(
So my question now becomes: Is there a way to make this work without having to use my own (re)implementation of File.setLastModified()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尽管在这种情况下错误消息有点误导,但您看到的是正常行为。
通过将 dwShareMode 设置为零打开目录,JDK 实际上会请求独占访问,这将导致任何其他访问尝试失败并出现共享冲突错误。 这同样适用于访问
来自其他流程和您自己的流程。
CreateFile
文档介绍了dwShareMode
参数:所以,看来您已经回答了自己的问题:您需要一个自定义
setLastModified
函数来指定FILE_SHARE_READ | 访问目录时FILE_SHARE_WRITE
。Although the error message is a bit misleading in this case, what you're seeing is normal behaviour.
By opening the directory with
dwShareMode
set to zero, the JDK is, in effect, asking for exclusive access, which will cause any other access attempt to fail with a sharing violation error. This applies equally to accessesfrom other processes and from within your own process.
The
CreateFile
documentation describes thedwShareMode
parameter:So, it seems you've answered your own question: you need a custom
setLastModified
function that specifiesFILE_SHARE_READ | FILE_SHARE_WRITE
when accessing the directory.