Node.js检查路径是文件还是目录


Answers:


609

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()

注意:

上述溶液throw一个ErrorIF; 例如,fileor或directory不存在。

如果您想要一个truefalse方法,请尝试fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();按约瑟夫在下面的评论中所述。


18
请注意,如果您关心一般应用程序的性能,通常最好使用异步版本。
AlexMA 2014年

45
请记住,如果目录或文件不存在,则将返回错误。
伊桑·米克

9
let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
约瑟夫·哈鲁什

请记住,如果文件或目录不存在,它将抛出需要捕获的异常,否则将导致异常退出。
谢尔盖·库兹涅佐夫

59

更新: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版本

这是您如何异步检测路径是文件还是目录的方法,这是在节点中推荐的方法。使用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月,这仍被视为实验性的吗?我们在哪里可以看到?-糟糕,当我单击上方的链接时,它已经稳定(这意味着不再进行实验),我看到了。
alfreema

20

认真地说,问题存在五年了,而且没有很好的门面吗?

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

14

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

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

显然,如果您要查找的文件没有扩展名,则需要确定文件系统。但请保持简单,直到您需要更复杂为止。

const path = require('path');

function isFile(pathItem) {
  return !!path.extname(pathItem);
}

2
显然,这并非在所有情况下都有效,但是如果您可以进行必要的假设,则比其他答案更快,更容易。
electrovir

1

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

答案是使用“ /”标识基于目录的路径。就像->“ / 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月

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


1

这是我使用的功能。没有人正在使用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;它,因为它已经试验了一年,最好不要依赖它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.