【问题标题】:fs.readdir failing on and don't know whyfs.readdir 失败,不知道为什么
【发布时间】:2020-01-04 04:06:47
【问题描述】:

运行节点应用程序以读取目录

fs.readdirSync('‎/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward');

我一直得到

 Stack:
    error properties: Object({ errno: -2, syscall: 'scandir', code: 'ENOENT', path: '‎/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward' })
    Error: ENOENT: no such file or directory, scandir '‎/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward'

但我知道目录在那里

ls -al /Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward
    total 0
    drwxr-xr-x@ 9 edwardthompson  staff  288 Jan 18  2019 .
    drwxr-xr-x@ 6 edwardthompson  staff  192 Aug 29 12:30 ..
    drwxr-xr-x@ 9 edwardthompson  staff  288 Jan 18  2019 Births
    drwxr-xr-x@ 4 edwardthompson  staff  128 Jan 18  2019 Census
    drwxr-xr-x@ 3 edwardthompson  staff   96 Jan 18  2019 Deaths
    drwxr-xr-x@ 7 edwardthompson  staff  224 Jan 18  2019 Marriages
    drwxr-xr-x@ 4 edwardthompson  staff  128 Jan 18  2019 Military
    drwxr-xr-x@ 3 edwardthompson  staff   96 Jan 18  2019 Other
    drwxr-xr-x@ 8 edwardthompson  staff  256 Jan 18  2019 books

不知道如何继续

fs.lstat 给了我相同的 ENOENT 结果。 Dropbox 目录有扩展属性(找不到 getfattr)

我试过 /user/... 并没有什么不同

【问题讨论】:

  • 可能是访问/Users/edwardthompson/ 目录的权限问题。您的节点环境是在同一个用户下运行,还是一个具有适当组访问权限的用户运行?
  • 也许尝试将硬盘盘符添加到路径中,例如C:/...
  • 仅供参考,堆栈输出中的路径以/User/ 开头,在您的函数调用和ls 调用中,它以/Users/ 开头
  • /User/ 是我的复制粘贴错误(我正在尝试一些事情)。 C:/ 在 linux 或 macos 文件系统上没有意义。我一直在尝试以某种方式查看它的权限,但我正在以自己的方式运行,我可以做到
  • 节点 fs.readdir 是否存在扩展属性 (xattr) 的问题?

标签: javascript node.js fs


【解决方案1】:

你可以试试path.resolve():

fs.readdirSync(path.resolve(‘Users’, ‘edwardthompson’, ‘Dropbox’, ‘Apps’, ‘EvidentiaSoftware’, ‘records’, ‘thompson-hayward’));

【讨论】:

  • 奇怪的是,路径解析给了我 /Users/edwardthompson/IdeaProjects/evidentia4/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward
【解决方案2】:
const path = require('path');

const dirName = path.join(__dirname, '‎/ (../)x? /records/thompson-hayward');

(../)x?将其替换为 ../ 你需要多少次

fs.readdirSync(dirName).forEach(folder => {
// code here
});

【讨论】:

  • path.join 给了我:/Users/edwardthompson/IdeaProjects/evidentia4/src/app/services/‎/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward ,这当然是错误的,但它揭示了两条路径之间的一些隐藏特征。我注意到我通常收到的错误消息在路径的基础前有一个空格 - 这个没有。
  • ths ../ 方法不适用于我的应用程序 - 目录现在是硬编码的,但将基于用户选择。
【解决方案3】:

您可以对隐藏角色的路径进行一些诊断工作,或许可以了解它是什么。

如果这会产生问题路径:

let p = '/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward';

然后,您可以这样做来查看第一个字符是什么:

 console.log(p.charCodeAt(0));

或者,输出字符串中的所有字符代码:

console.log(p.split("").map(chr => chr.charCodeAt(0).toString()).join(","));

这里是一个可运行的 sn-p(它不会在我的计算机上重现您的问题,但可能会在您的计算机上显示某些内容):

let p = '/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward';
let charCodes = p.split("").map(chr => chr.charCodeAt(0));
let str = charCodes.map((code, index) => {
    return `<tr><td>${p.charAt(index)}</td><td>${code.toString()}</td><td> 0x${code.toString(16)}</td></tr>`
}).join("");
document.write(`<style>table.colright td:nth-child(2), table.colright th:nth-child(2), table.colright td:nth-child(3), table.colright th:nth-child(3) {
  text-align: right;
}</style>`);
document.write("<table class='colright'>")
document.write("<thead><tr><th>&nbsp;char<br>&nbsp;</th><th>&nbsp;decimal<br>value</th><th>hex<br>&nbsp;&nbsp;&nbsp;&nbsp;value</th></tr></thead>");    
document.write("<tbody>");
document.write(str);
document.write("</tbody></table>");

我唯一可行的理论(这是一个未经证实的猜测)是,以某种方式开始字符串的 /U 被解释为仅在您的系统上手动指定的 unicode 字符的开头。它应该是 \u 作为 unicode 前缀,而不是 /U,但它肯定会以某种方式误解 /U


仅供参考,您可能还想这样做:

console.log(path.sep) 

只是为了确保您的路径分隔符不适合您的平台。

【讨论】:

    【解决方案4】:

    "/Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward" 不是正确的路径 - 此路径以 / 开头,即根目录。

    在 Linux 中,./ 是目录的快捷方式。

    试试这样的东西“./Users/edwardthompson/Dropbox/Apps/EvidentiaSoftware/records/thompson-hayward”

    这里是一个工作示例的链接,如果您省略 . https://repl.it/@joshuaaguilar20/FrequentFunctionalFraction

          var fs = require('fs');
    
    fs.writeFile('./newFile.txt', 'Hello World', function(error){
      if(error){
        throw error;
      } else {
        console.log('success');
      }
    });
    
    /* let wrong = fs.readdirSync("/newDir", function (err) {
      console.log(err)
    }) */
    
    /* 
    Returns Error 
    Error: ENOENT: no such file or directory, scandir '/newDir'
        at Object.readdirSync (fs.js:790:3)
        at evalmachine.<anonymous>:11:12
        at Script.runInContext (vm.js:133:20)
        at Object.runInContext (vm.js:311:6)
        at evaluate (/run_dir/repl.js:133:14)
        at ReadStream.<anonymous> (/run_dir/repl.js:116:5)
        at ReadStream.emit (events.js:198:13)
        at addChunk (_stream_readable.js:288:12)
        at readableAddChunk (_stream_readable.js:269:11)
        at ReadStream.Readable.push (_stream_readable.js:224:10)
    
     */
    
    
    //Correct 
    
    let x = fs.readdirSync("./newDir", function (err) {
      //adding ./ allows unix to find the Dir 
      console.log(err)
    })
    
    console.log(x)
    

    【讨论】:

      【解决方案5】:

      一种简单的调试方法是尝试读取位于 /Users/{username} 中的不同目录。如果它有效,您可能需要查看 readdir 的符号链接问题。 Dropbox 很可能创建了一个未正确解析的符号链接。

      您可以使用fs.realpath() or fs.realpathSync 获取您要查找的目录的真实路径,然后在真实路径上使用readdir。

      【讨论】:

      • 这对我有用,非常感谢! readdirSync 在我的 Mac 上本地工作,但在使用 Ubuntu 的 docker 容器中它失败了。所以我不得不像你建议的那样使用 realpathSync('/some/path') 并将结果传递给 fs.readdirSync
      猜你喜欢
      • 2017-04-24
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      相关资源
      最近更新 更多