You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu环境下Node.js出现ENOENT错误,但目标文件实际存在

解决SMB文件复制随机出现ENOENT错误的问题

可能的原因及对应方案:

  • SMB文件系统的同步延迟
    网络共享(SMB)的文件元数据同步存在延迟是常见问题。glob扫描到文件列表后,文件可能还没在底层文件系统完成写入就绪,这时候用fs.readFileSync读取就会触发ENOENT。而文件管理器通常会做缓存或延迟加载,所以能正常看到文件。
    解决办法:给每个文件读取操作加重试机制,失败后等待几百毫秒再重试2-3次。示例代码:

    function readFileWithRetry(path, retries = 3, delay = 500) {
      try {
        return fs.readFileSync(path);
      } catch (err) {
        if (err.code === 'ENOENT' && retries > 0) {
          setTimeout(() => {}, delay); // 等待后重试
          return readFileWithRetry(path, retries - 1, delay);
        }
        throw err;
      }
    }
    
  • glob的实时性不足
    glob默认仅基于目录条目返回文件列表,不会检查文件是否真的可访问。如果CCTV文件处于边写入边被扫描的状态(比如监控还在写入该文件),就会出现条目存在但无法读取的情况。
    解决办法:在读取前先检查文件是否可读,用fs.accessSync做前置校验:

    for (const file of filesArr) {
      try {
        fs.accessSync(file, fs.constants.R_OK); // 检查文件可读权限
        const data = fs.readFileSync(file);
        // 执行后续复制逻辑
      } catch (err) {
        if (err.code === 'ENOENT') {
          console.log(`文件暂不可访问,跳过或稍后重试: ${file}`);
        }
      }
    }
    
  • SMB挂载的稳定性问题
    偶尔的网络波动可能导致SMB挂载点临时失去连接,此时读取文件会触发ENOENT。文件管理器通常会自动重新连接,但脚本不会主动处理这类情况。
    解决办法:在脚本中加入挂载点连通性检查,比如定期读取挂载点下的固定测试文件;若捕获到ENOENT错误,可尝试重新挂载SMB共享(需sudo权限,适合受控运行环境)。

  • 文件路径的隐形问题
    部分SMB共享可能返回带有不可见字符的文件名,或者路径大小写在SMB(大小写不敏感)与Ubuntu本地文件系统(大小写敏感)间存在差异,导致glob拿到的路径和实际可读路径不匹配。
    解决办法:打印出错文件的路径,用console.log(Buffer.from(file).toString('hex'))排查是否有不可见字符;或读取前对路径做标准化处理:

    const normalizedPath = path.normalize(file);
    

内容的提问来源于stack exchange,提问作者seventeen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 01:03:23