Java FindFirstFileW何时将上一个错误设置为错误\u没有\u更多\u文件,而不是错误\u找不到文件? 这个问题。
理论上,我有一个简单的方法将文件从一个目录复制到另一个目录,但在某些设置下,这些目录是作为某些Windows Server 2016的网络共享提供的。在某些情况下,由于Java在尝试规范化路径的过程中抛出了一个Java FindFirstFileW何时将上一个错误设置为错误\u没有\u更多\u文件,而不是错误\u找不到文件? 这个问题。,java,windows,filesystems,Java,Windows,Filesystems,理论上,我有一个简单的方法将文件从一个目录复制到另一个目录,但在某些设置下,这些目录是作为某些Windows Server 2016的网络共享提供的。在某些情况下,由于Java在尝试规范化路径的过程中抛出了一个IOException,所以复制偶尔会失败,我确信这是因为在该操作过程中发生的 如果找不到文件,则会失败并设置错误\u文件\u未找到。JavaOtoh甚至是一些特殊的和其他的。不在被忽略错误列表中的是ERROR\u NO\u MORE\u文件: if ((errval == ERROR_F
IOException
,所以复制偶尔会失败,我确信这是因为在该操作过程中发生的
如果找不到文件,则会失败并设置错误\u文件\u未找到
。JavaOtoh甚至是一些特殊的和其他的。不在被忽略错误列表中的是ERROR\u NO\u MORE\u文件
:
if ((errval == ERROR_FILE_NOT_FOUND)
|| (errval == ERROR_DIRECTORY)
|| (errval == ERROR_PATH_NOT_FOUND)
|| (errval == ERROR_BAD_NETPATH)
|| (errval == ERROR_BAD_NET_NAME)
|| (errval == ERROR_ACCESS_DENIED)
|| (errval == ERROR_NETWORK_UNREACHABLE)
|| (errval == ERROR_NETWORK_ACCESS_DENIED)) {
return 0;
}
但由于某些原因,Windows有时会决定将该错误准确地设置为最后一个错误,这可以通过Process Monitor看到,并且该错误完全符合Java在其stacktrace中提供的错误消息
10:12:06,6244515 integration.exe 6928 QueryDirectory \\HOST\SHARE$\DocBeam3\[...].zip NO MORE FILES Filter: 20191106-081920-[...].zip
vs
补充意见。
现在有趣的是,守护进程并不总是在每个文件副本上失败,但只是偶尔失败,很少失败。但是,如果失败,它似乎与目标目录中已有的其他目录和文件有关。虽然这些与守护进程完全无关,并且根据ProcMon的说法,它们没有得到迭代或其他东西,但它们的纯粹存在似乎已经起到了作用。如果我简单地删除所有这些文件和目录,并以这种方式清空目标目录,复制会立即再次成功。这很有趣,因为在我的本地设置中,目标目录中有文件和目录似乎没有任何影响:复制从不失败,尤其是ProcMon记录的事件从不是ERROR\u NO\u MORE\u files
。清空发生问题的安装程序上的目录后,ProcMon也会再次记录错误\u文件\u未找到
这个问题。
因此,似乎出于某些原因,在当前未知的情况下,Windows决定使用ERROR\u NO\u MORE\u FILES
作为wcanonicalize
使用的FindFirstFileW
调用中的最后一个错误。因为Java在其异常列表中没有这一点,所以在这些情况下复制失败,即使这似乎是一种完全有效的情况。除此之外,我看不到任何真正的错误。此外,具有不同错误代码的列表的纯粹存在已经证明,FindFirstFileW
已知在不同的情况下设置不同的错误代码
那么,FindFirstFileW
何时将上次错误设置为error\u NO\u MORE\u FILES
而不是error\u FILE\u NOT\u FOUND
?
我希望能更好地理解到底是什么触发了这个问题。设置条件bp,当
FindFirstFileW
returnERROR\u无更多文件
或更改src代码(如果可以的话),以捕捉这种情况。但出于设计,这决不能是错误的。如果初始查询中没有更多文件,则通过win32文件系统(转换为错误文件\u未找到
)返回错误状态\u无此类文件。和STATUS\u NO\u MORE\u文件
在下一次查询中-@RbMm,请特别参阅。协议明确规定,如果第一次查询没有匹配的文件,则必须返回状态\u否\u这样的\u文件
。在这种情况下,如果文件系统或重定向程序返回状态\u无更多\u文件
,则该文件系统或重定向程序存在错误。findfirstfile
封装本机调用NtOpenFile
,该调用返回引用目录的新文件对象的句柄,以及NtQueryDirectoryFile
,其中ReturnSingleEntry
参数为true,因此它只返回第一个结果。查询状态与文件对象相关联。在Windows API中,此内核对象的句柄由“搜索句柄”封装。后者实际上是一个记录,包含真实句柄和一个缓冲区,用于在后续的FindNextFileW
调用中读取每个NtQueryDirectoryFile
系统调用的多个条目。请注意NtOpenFile
和NtCreateFile
都通过IoCreateFileEx
创建一个新的文件对象,其中,Io
是I/O管理器例程的内核前缀。I/O管理器依次为设备对象(例如“\Device\Mup”)实现解析例程。此解析例程将设备对象作为新文件对象打开。如果它是一个文件系统,或者由一个文件系统装载,那么文件系统将解析剩余路径并将对象与文件系统结构关联。通常这是共享文件控制块(FCB)和每个文件上下文控制块(CCB)。目录查询的状态在CCB中。因此,当FindFirstFileW
调用NtOpenFile
时,它会获取一个与仅为该文件对象创建的CCB关联的文件对象的句柄。因此,目录查询状态不可能与由不相关的FindFirstFileW
调用创建的文件对象合并。目录查询是完全独立的。
19:08:03,7485947 java.exe 6232 QueryDirectory C:\Users\[...].zip NO SUCH FILE Filter: 20191022-143101-[...].zip