【问题标题】:Node.js check if path is file or directoryNode.js 检查路径是文件还是目录
【发布时间】:2013-03-15 21:02:15
【问题描述】:

我似乎无法获得任何解释如何执行此操作的搜索结果。

我只想知道给定的路径是文件还是目录(文件夹)。

【问题讨论】:

    标签: node.js path directory filesystems fs


    【解决方案1】:

    下面应该告诉你。来自docs

    fs.lstatSync(path_string).isDirectory() 
    

    从 fs.stat() 和 fs.lstat() 返回的对象属于这种类型。

    stats.isFile()
    stats.isDirectory()
    stats.isBlockDevice()
    stats.isCharacterDevice()
    stats.isSymbolicLink() // (only valid with fs.lstat())
    stats.isFIFO()
    stats.isSocket()
    

    注意:

    上述解决方案throwError if;例如,filedirectory 不存在。

    如果您想要truefalse 方法,请尝试fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();,正如Joseph 在下面的cmets 中提到的那样。

    【讨论】:

    • 请注意,如果您关心一般应用程序的性能,异步版本通常更可取。
    • 请记住,如果目录或文件不存在,那么您将得到一个错误返回。
    • let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
    • 请记住,如果文件或目录不存在,则会抛出需要捕获的异常,否则会导致异常退出。
    • 我觉得奇怪的是,当他们第一次制作 lstat 时,他们并没有在其中包含一个 exists() 函数?我想这就是为什么 node_modules 比黑洞更深的原因。
    【解决方案2】:

    更新:Node.Js >= 10

    我们可以使用新的fs.promises API

    const fs = require('fs').promises;
    
    (async() => {
        const stat = await fs.lstat('test.txt');
        console.log(stat.isFile());
    })().catch(console.error)
    

    任何 Node.Js 版本

    以下是检测路径是文件还是目录的方法异步,这是 node.js 中推荐的方法。 使用fs.lstat

    const fs = require("fs");
    
    let path = "/path/to/something";
    
    fs.lstat(path, (err, stats) => {
    
        if(err)
            return console.log(err); //Handle error
    
        console.log(`Is file: ${stats.isFile()}`);
        console.log(`Is directory: ${stats.isDirectory()}`);
        console.log(`Is symbolic link: ${stats.isSymbolicLink()}`);
        console.log(`Is FIFO: ${stats.isFIFO()}`);
        console.log(`Is socket: ${stats.isSocket()}`);
        console.log(`Is character device: ${stats.isCharacterDevice()}`);
        console.log(`Is block device: ${stats.isBlockDevice()}`);
    });
    

    使用同步 API 时的注意事项:

    当使用同步形式时,任何异常都会立即抛出。 您可以使用 try/catch 来处理异常或允许它们冒泡。

    try{
         fs.lstatSync("/some/path").isDirectory()
    }catch(e){
       // Handle error
       if(e.code == 'ENOENT'){
         //no such file or directory
         //do something
       }else {
         //do something else
       }
    }
    

    【讨论】:

    • 截至 2020 年 3 月,这仍被认为是实验性的吗?我们在哪里可以看到? -- 糟糕,当我点击上面的链接时,我看到它现在已经稳定了(这意味着不再是实验性的)。
    【解决方案3】:

    说真的,问题存在五年,没有漂亮的外观?

    function isDir(path) {
        try {
            var stat = fs.lstatSync(path);
            return stat.isDirectory();
        } catch (e) {
            // lstatSync throws an error if path doesn't exist
            return false;
        }
    }
    

    【讨论】:

    • [Error: EACCES: permission denied, scandir '/tmp/snap.skype'] 当我提供 /tmp/ 这是一个目录并且可访问。
    【解决方案4】:

    根据您的需要,您可能可以依赖节点的path 模块。

    您可能无法访问文件系统(例如,该文件尚未创建)并且您可能希望避免访问文件系统,除非您确实需要额外的验证。如果您可以假设您正在检查的内容遵循.<extname> 格式,只需查看名称即可。

    显然,如果您正在寻找一个没有 extname 的文件,您需要点击文件系统来确定。但在您需要更复杂之前,请保持简单。

    const path = require('path');
    
    function isFile(pathItem) {
      return !!path.extname(pathItem);
    }
    

    【讨论】:

    • 显然这并不适用于所有情况,但如果您可以做出必要的假设,它比其他答案更快更容易。
    • 目录可以命名为folder.txt,这表示它是一个文件,或者该文件可以是LICENSE,没有扩展名
    【解决方案5】:

    这是我使用的一个函数。没有人在这篇文章中使用promisifyawait/async 功能,所以我想我会分享。

    const promisify = require('util').promisify;
    const lstat = promisify(require('fs').lstat);
    
    async function isDirectory (path) {
      try {
        return (await lstat(path)).isDirectory();
      }
      catch (e) {
        return false;
      }
    }
    

    注意:我不使用require('fs').promises;,因为它已经实验一年了,最好不要依赖它。

    【讨论】:

      【解决方案6】:

      如果你在遍历目录时需要这个1

      自 Node 10.10+ 起,fs.readdir 具有 withFileTypes 选项,这使其返回目录条目 fs.Dirent 而不仅仅是文件名。目录条目包含其name 和有用的方法,例如isDirectoryisFile,因此您无需显式调用fs.lstat

      你可以这样使用它:

      import { promises as fs } from 'fs';
      
      // ./my-dir has two subdirectories: dir-a, and dir-b
      const dirEntries = await fs.readdir('./my-dir', { withFileTypes: true });
      
      // let's filter all directories in ./my-dir
      const onlyDirs = dirEntries.filter(de => de.isDirectory()).map(de => de.name);
      // onlyDirs is now [ 'dir-a', 'dir-b' ]
      

      1) 因为我就是这样找到这个问题的。

      【讨论】:

        【解决方案7】:

        上面的答案检查文件系统是否包含文件或目录的路径。但它不能单独识别给定路径是文件还是目录。

        答案是使用“/”来识别基于目录的路径。比如 --> "/c/dos/run/."

        类似于尚未写入的目录或文件的路径。或者来自不同计算机的路径。或者同时存在同名文件和目录的路径。

        // /tmp/
        // |- dozen.path
        // |- dozen.path/.
        //    |- eggs.txt
        //
        // "/tmp/dozen.path" !== "/tmp/dozen.path/"
        //
        // Very few fs allow this. But still. Don't trust the filesystem alone!
        
        // Converts the non-standard "path-ends-in-slash" to the standard "path-is-identified-by current "." or previous ".." directory symbol.
        function tryGetPath(pathItem) {
            const isPosix = pathItem.includes("/");
            if ((isPosix && pathItem.endsWith("/")) ||
                (!isPosix && pathItem.endsWith("\\"))) {
                pathItem = pathItem + ".";
            }
            return pathItem;
        }
        // If a path ends with a current directory identifier, it is a path! /c/dos/run/. and c:\dos\run\.
        function isDirectory(pathItem) {
            const isPosix = pathItem.includes("/");
            if (pathItem === "." || pathItem ==- "..") {
                pathItem = (isPosix ? "./" : ".\\") + pathItem;
            }
            return (isPosix ? pathItem.endsWith("/.") || pathItem.endsWith("/..") : pathItem.endsWith("\\.") || pathItem.endsWith("\\.."));
        } 
        // If a path is not a directory, and it isn't empty, it must be a file
        function isFile(pathItem) {
            if (pathItem === "") {
                return false;
            }
            return !isDirectory(pathItem);
        }
        

        节点版本:v11.10.0 - 2019 年 2 月

        最后的想法:为什么还要访问文件系统?

        【讨论】:

        • 如果文件夹名称的末尾有一个点,比如.git 甚至myFolder.txt,该怎么办?
        • 您必须了解 posix 文件路径约定(由于 Windows 在内核级别兼容 posix,因此 Windows 部分遵守了哪些约定)。请阅读stackoverflow.com/questions/980255/…en.wikipedia.org/wiki/…
        • 我真的没有回答这个问题吗? .git 和 myFolder.txt 可以是文件夹或文件。你不知道,直到你检查。由于文件夹也被视为文件,因此您不能拥有同名的文件夹和文件。 .git/.和 myFolder.txt/。都是文件夹。 .git/ 和 myFolder.txt/ 是该文件夹中的所有文件。 man readline 记录了这个(模糊地)。孤独的。很特别。包含 .不是。
        • 。和 .. 都很特别
        猜你喜欢
        • 2018-12-18
        • 2011-12-26
        • 2013-08-14
        • 2015-07-30
        • 2012-01-15
        • 2017-08-16
        • 2015-06-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多