问题
The problem.
I have a problem with some Java daemon simply copying files from one directory into another in theory, but under some setups those directories are provided as network shares of some Windows Server 2016. Under some circumstances it occasionally happens that copying fails because of Java throwing an IOException
during trying to canonicalize paths and I'm somewhat sure that this happens because during that operation FindFirstFileW is used.
If a file is not found, that simply fails and sets ERROR_FILE_NOT_FOUND
as last error. Java OTOH is prepared to get that error and even some special others and simply ignore them. What is NOT part of that list of ignored errors is ERROR_NO_MORE_FILES
:
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;
}
But for some reason Windows sometimes decide to set exactly that error as the last one, which can be seen using Process Monitor and that error perfectly fits to the error message Java provides in its stacktrace.
10:12:06,6244515 integration.exe 6928 QueryDirectory \\HOST\SHARE$\DocBeam3\[...].zip NO MORE FILES Filter: 20191106-081920-[...].zip
vs.
19:08:03,7485947 java.exe 6232 QueryDirectory C:\Users\[...].zip NO SUCH FILE Filter: 20191022-143101-[...].zip
Additional observations.
The interesting thing now is that the daemon doesn't fail always on each and every file copy, but only sometimes, somewhat rarely. But if it fails it seems to have to do with other directories and files being available in the target directory already. While those are completely unrelated to the daemon and according to ProcMon those don't get iterated or stuff, their pure existance seems to make a difference already. If I simply delete all of those files and directories and empty the target directory this way, copying instantly succeeds again. That's interesting because having files and directories in the target directory in my local setup doesn't seem to have any influence: Copying never fails and especially the event logged by ProcMon NEVER is ERROR_NO_MORE_FILES
as well. After emptying the directory on the setup where the problem happens, ProcMon logs ERROR_FILE_NOT_FOUND
again as well.
The question.
So it seems that for some reason under some currently unknown circumstances, Windows decides to use ERROR_NO_MORE_FILES
as last error in the calls to FindFirstFileW
used by wcanonicalize
. Because Java doesn't have that on its exception list, copying fails in those circumstances, even if it seems to be a perfectly valid situation. I don't see any real error otherwise. Additionally, the pure existence of the list with different error codes already proves that FindFirstFileW
is known to set different error codes under different circumstances.
So, when does FindFirstFileW
set last error to be ERROR_NO_MORE_FILES
instead of ERROR_FILE_NOT_FOUND
?
I'm hoping to better understand what might trigger the problem at all this way.
来源:https://stackoverflow.com/questions/58825963/when-does-findfirstfilew-set-last-error-to-be-error-no-more-files-instead-of-err