Node.js проверяет, является ли путь файлом или каталогом


381

Я не могу получить результаты поиска, которые объясняют, как это сделать.

Все, что я хочу сделать, это знать, является ли данный путь файлом или каталогом (папкой).

Ответы:


611

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

НОТА:

Выше решение будет если; Например, или не существует.throwErrorfiledirectory

Если вы хотите trueили falseподход, попробуйте, fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();как упоминал Джозеф в комментариях ниже.


18
Обратите внимание, что асинхронная версия обычно предпочтительнее, если вы заботитесь об общей производительности приложения.
AlexMA

45
Помните, что если каталог или файл не существует, вы получите сообщение об ошибке.
Итан Мик

9
let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
Йосеф Харуш

Имейте в виду, что если файл или каталог не существует, он выдаст исключение, которое необходимо перехватить, иначе это приведет к аварийному завершению.
Сергей Кузнецов

60

Обновление: Node.Js> = 10

Мы можем использовать новый API fs.promises.

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 года? Где мы можем посмотреть? - Ой, когда я нажимаю на ссылку выше, я вижу, что теперь она стабильна (что означает, что она больше не экспериментальная).
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>формату, просто посмотрите на название.

Очевидно, что если вы ищете файл без extname, вам нужно будет поразить файловую систему, чтобы быть уверенным. Но будьте проще, пока вам не понадобятся более сложные.

const path = require('path');

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

2
Очевидно, что это не сработает во всех ситуациях, но гораздо быстрее и проще, чем другие ответы, если вы можете сделать необходимые предположения.
электровир

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

Последняя мысль: зачем вообще попадать в файловую систему?


1

Вот функция, которую я использую. Никто не использует promisifyи не await/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;потому что это экспериментально в течение одного года, лучше не полагаться на это.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.