在 Windows 上规范化路径时,Java 是否需要支持 ERROR_NO_MORE_FILES?

2023-12-05

问题。

一些用 Java 实现的守护进程在 Windows 7 上运行,将文件从一个目录复制到另一个目录,而源目录和目标目录都是 Windows Server 2016 托管的网络共享。复制是使用 Apache Commons IO 完成的,偶尔会发生此过程失败的情况具有以下堆栈跟踪和一条类似于“没有更多文件”的消息:

java.io.IOException: Es sind keine weiteren Dateien vorhanden
        at java.io.WinNTFileSystem.canonicalize0(Native Method)
        at java.io.WinNTFileSystem.canonicalize(Unknown Source)
        at java.io.File.getCanonicalPath(Unknown Source)
        at org.apache.commons.io.FileUtils.copyFile(FileUtils.java:642)
        at org.apache.commons.io.FileUtils.copyFileToDirectory(FileUtils.java:587)
        at org.apache.commons.io.FileUtils.copyFileToDirectory(FileUtils.java:558)
        at de.am_soft.osgi.dokliste.eingaenge.impl.internal.Eingang.copyFilesToDbxmlFolders(Eingang.java:283)

Apache Commons IO 在第 642 行使用以下代码,该行实际上只是以下内容if,也不例外:

if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
    throw new IOException("Source '" + srcFile + "' and destination '" + destFile + "' are the same");
}

所以问题不在于复制本身,而在于已经生成规范路径。使用进程监视器1在守护进程运行的客户端也证明了这一点。以下是守护进程明确记录上述异常之前的最后一个事件,尝试使用 Logback 等发送错误邮件。该事件的结果(NO MORE FILES)非常适合堆栈跟踪的错误消息:

10:12:06,6244515        integration.exe 6928    QueryDirectory  \\HOST\SHARE$\DocBeam3\[...].zip  NO MORE FILES   Filter: 20191106-081920-[...].zip

此外,查看 ProcMon 的前几行,可以肯定异常发生在destFile仅有的。在我的本地计算机上执行守护进程会导致以下记录的事件(NO SUCH FILE) 总是:

19:08:03,7485947    java.exe    6232    QueryDirectory  C:\Users\[...].zip  NO SUCH FILE    Filter: 20191022-143101-[...].zip

我已经调试了本机方法并遇到了lastErrorReportable,它显式检查一些特殊的错误代码并且不包含ERROR_NO_MORE_FILES从第一个事件开始,虽然它确实包含ERROR_FILE_NOT_FOUND从第二个开始:

    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;
    }

https://github.com/openjdk/jdk/blob/master/src/java.base/windows/native/libjava/canonicalize_md.c#L131

所以似乎每当ERROR_NO_MORE_FILES发生时,规范化路径只会因错误而中止,而不是像其他错误一样忽略它:

if (!lastErrorReportable()) {
   if (!(dst = wcp(dst, dend, L'\0', src, src + wcslen(src)))){
       goto err;
   }
    break;
} else {
    goto err;
}

https://github.com/openjdk/jdk/blob/master/src/java.base/windows/native/libjava/canonicalize_md.c#L246

抛出的异常与我得到的非常吻合,给定的消息只是在我的情况下未使用的后备:

if (rv == NULL && !(*env)->ExceptionCheck(env)) {
    JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
}

https://github.com/openjdk/jdk/blob/master/src/java.base/windows/native/libjava/WinNTFileSystem_md.c#L258

额外的观察结果。

现在有趣的是,守护进程并不总是在每个文件副本上失败,而只是有时失败,有点罕见。但如果失败,则似乎与目标目录中已存在的其他目录和文件有关。虽然这些与守护进程完全无关,并且根据 ProcMon 的说法,它们不会被迭代或其他东西,但它们的纯粹存在似乎已经产生了影响。如果我只是删除所有这些文件和目录并以这种方式清空目标目录,复制就会立即再次成功。这很有趣,因为在我的本地设置中的目标目录中包含文件和目录似乎没有任何影响:复制永远不会失败,尤其是 ProcMon 记录的事件永远不会ERROR_NO_MORE_FILES以及。清空发生问题的设置上的目录后,ProcMon 会记录ERROR_FILE_NOT_FOUND再次也是如此。

问题。

因此,似乎出于某种原因,在某些当前未知的情况下,Windows 决定使用ERROR_NO_MORE_FILES作为调用中的最后一个错误FindFirstFileW被使用过wcanonicalize。因为 Java 的异常列表中没有这种情况,所以在这些情况下复制会失败,即使它看起来是完全有效的情况。否则我没有看到任何真正的错误。

所以应该ERROR_NO_MORE_FILES被添加到lastErrorReportable?如果是这样,我实际上需要问谁? :-)


此行为是由 Windows Server 2019 服务器(文件服务器)与早期版本的 Windows(客户端)之间的 SMB 不兼容引起的。目录元数据的缓存处理方式不同,这会在读取包含许多文件和文件夹的共享时导致此问题。

不幸的是,微软尚未发布针对此错误的修复程序。

解决方法是使用以下注册表设置禁用客户端上的 SMB 元数据缓存:HKLM\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\DirectoryCacheLifetime=0 (DWORD)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Windows 上规范化路径时,Java 是否需要支持 ERROR_NO_MORE_FILES? 的相关文章

随机推荐

  • 算法复杂度 时间

    我目前无法识别和理解以下算法的复杂时间 背景 有一个文件列表 每个文件包含一个候选 ID 列表 文件的数量和其中的候选人数量都是不固定的 您如何计算负责以下任务的算法的时间复杂度 读取每个文件并将所有唯一的候选 ID 添加到哈希集中 Tha
  • 如何检查iOS版本是否可用字体?

    我目前正在开发一个使用 ChalkboardSE Regular 字体的应用程序 我的部署目标是 4 0 该字体在 4 1 中不可用 但在 4 3 中受支持 检查字体是否存在的最佳方法是什么 如果不存在 请在 提前致谢 T UIFont f
  • Spring Data Rest:如何从存储库公开 json 模式 (2.0.0.M1)

    我在源代码中看到 Spring DATA Rest 可以通过以下 URL 为存储库公开 Json 架构 repository schema 有谁知道如何配置这个吗 有 RepositorySchemaController org sprin
  • Codeigniter 2.1.2 和 Facebook-PHP-SDK 3.1.1

    我正在通过 Codeigniter 2 1 2 和 Facebook PHP SDK 3 1 1 开发一个简单的身份验证 但我不知道为什么它现在可以工作 我已将 src 文件夹 https github com facebook faceb
  • 什么时候结构体太大? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的结构与类 抱歉 如果这是一个开放式问题 但我只想知道我的结构是否太大 我想使用结构体的原因是因为我知道它们比类更快 我认为我真的需要这种速度 我发现如果你的结构太大 它实际上会减慢你的程序 所
  • 我的网页忽略 CSS 文件中的更改

    无论我在 css 文件中进行什么更改 页面都保持不变 而且 无论是更改链接标记以使其指向另一个 css 文件还是完全删除它都没有什么区别 应用 html 代码中的其他更改 网页的源代码显示了应有的一切 当我将链接标签从前一个文件重定向到我现
  • Azure 函数无法正常工作“无法在脚本代码中声明命名空间”

    我是一名 Java 微服务人员 对 NET 不太感兴趣 在 StackOverflow 社区的帮助下 我能够为我的问题获得工作代码 该代码在本地完美运行 但是当我尝试将其作为函数移动到 Azure 时 我收到错误 请指导 Code 本地工作
  • 在 R 中按降序排列带有“null”的条形图的条形

    我想创建一个带有降序条形的条形图 在下面的图中 由于 NA 出现在 a1 向量的第二个位置 所以在创建图时它被推到最后 但是 我希望 NA 条仅出现在第二个位置 请在此帮助我 因为我想在不修改数据的情况下实现此目的 library ggpl
  • 由于 PIC,无法从程序集中的 x86-64 对象链接共享库

    我正在将共享库从 32 位移植到 64 位 它由一些导出多个过程的程序集 为 NASM 编写 和一些高级 C 粘合代码组成 我正在使用 NASM 2 10 01 和 GNU ld 2 22 的 64 位 Debian 机器上进行构建 解决了
  • (Quicksight) 如何仅对唯一字段中的值求和

    我的数据集有一个 Invoice No 字段 我想对其成本进行求和 所有发票号码都是唯一的并且具有one成本价值 但是 由于每个 Invoice No 中有多个 Part No 字段 Quicksight 会将这一成本乘以每张发票中的零件编
  • 通过 JavaScript 隐藏来自 Google 的链接

    我们有一些想要向 Google 隐藏的链接 使用 Javascript 来 隐藏 链接 但让它为真正的客户工作 SEO 机构告诉我 最好的方法是对链接进行 Base64 编码并通过 javascript 调用它 a href Link a
  • 可以对两个可能的表之一创建 MySQL 外键吗?

    好吧 这是我的问题 我有三张桌子 地区 国家 州 国家可以在区域内 州也可以在区域内 区域是食物链的顶端 现在我添加一个包含两列的popular areas 表 region id 和popular place id 是否可以使popula
  • 通过相机使用动态坐标捕获图像

    我正在制作一个基于相机的应用程序 我在相机上放置了一个矩形视图 当我使用捕获图像时new Camera PictureCallback 我裁剪了该图像 以便它将获得矩形的一部分 嗯 它工作正常 现在我实施了View OnTouchListe
  • Laravel - 三个模型的数据透视表 - 如何插入相关模型?

    我有三个具有多对多关系的模型 User Activity Product 桌子看起来像id name 每个模型中都有函数 例如在用户模型中 public function activities return this gt belongsT
  • 使用 fetch 进行 WebAudio 流式传输:DOMException:无法解码音频数据

    我正在尝试使用 Chrome 51 播放来自 fetch API 的无限流 网络摄像头音频流为 Microsoft PCM 16 位 单声道 11025 Hz 该代码对于 mp3 文件几乎可以正常工作 除了一些小故障 但它对于 wav 文件
  • Java Set 获取重复条目

    JavaDoc 将集合定义为 不包含重复元素的集合 更正式地说 设置 不包含使得 e1 equals e2 的元素对 e1 和 e2 为了验证这一点 我创建了一个非常简单的程序 import java util HashSet public
  • 使用 CCHmac() 生成 HMAC swift sdk8.3

    在 SDK8 3 之前 我是通过这种方式生成 hmac 的 现在我在 CCHmac 函数上遇到错误 由于我是初学者 我不知道如何解决它 在此先感谢您的帮助 xcode 警告 无法使用类型为 UInt32 CChar UInt CChar U
  • 从 OBJ 文件导入时如何在 glTexCoordPointer 中设置/计算纹理缓冲区

    我正在 Android 中解析 OBJ 文件 我的目标是渲染和显示该对象 除了正确的纹理映射之外 一切都工作正常 将资源 图像导入 opengl 等工作正常 我不知道如何将 obj 文件中的纹理相关数据填充到纹理缓冲区对象中 在 OBJ 文
  • 如何读取无符号整型的特定位

    我有一个 uint8 t 我需要读 写特定位 我将如何去做这件事 具体来说 我的意思是 我需要写入一个值的前 7 位 然后读取另一个值的最后一位 编辑 忘记指定 我将把它们设置为大端 您正在寻找位掩码 学习如何使用 C 的按位运算符 等等都
  • 在 Windows 上规范化路径时,Java 是否需要支持 ERROR_NO_MORE_FILES?

    问题 一些用 Java 实现的守护进程在 Windows 7 上运行 将文件从一个目录复制到另一个目录 而源目录和目标目录都是 Windows Server 2016 托管的网络共享 复制是使用 Apache Commons IO 完成的