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

Кажется, я не получаю никаких результатов поиска, которые объясняют, как это сделать.

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

Ответ 1

fs.lstatSync(path_string).isDirectory() должен сказать вам. Из docs:

Объекты, возвращаемые из fs.stat() и fs.lstat(), относятся к этому типу.

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

Ответ 2

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

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

Экспериментальная Эта функция все еще находится в активной разработке и может подвергаться изменениям, не имеющим обратной совместимости, или даже удалению в любой будущей версии. Использование этой функции не рекомендуется в производственных средах. Экспериментальные функции не подчиняются модели семантического управления версиями Node.js.

const fs = require('fs').promises;

(async() => {

        try {
            const stat = await fs.lstat('test.txt');
            console.log(stat.isFile());
        } catch(err) {
            console.error(err);
        }
})();

Любая версия 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
   }
}

Ответ 3

Серьезно, вопрос существует пять лет и нет красивого фасада?

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;
    }
}

Ответ 4

Ответы выше проверяют, содержит ли файловая система путь к файлу или каталогу. Но он не определяет, является ли данный путь одним файлом или каталогом.

Ответ заключается в том, чтобы определить пути на основе каталогов, используя "/". как → "/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

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

Ответ 5

В зависимости от ваших потребностей, вы, вероятно, можете положиться на модуль path узла.

Возможно, вам не удастся поразить файловую систему (например, файл еще не был создан) и, возможно, вы захотите избежать попадания в файловую систему, если вам действительно не нужна дополнительная проверка. Если вы можете сделать предположение, что то, что вы проверяете, имеет следующий формат .<extname>, просто посмотрите на имя.

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

const path = require('path');

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

Ответ 6

 var path = "app/static";
 var result = fs.existsSync(path);
 if(result) {
    fs.readFile(path, (err,data)=> {
        response.write(data);
        response.end();
    })
 }
 else {
   response.writeHead(404);
   fs.readFile("app/static/error.html", (err,data)=> {
       response.write(data);
       response.end();
   });

 }

Ответ 7

Здесь отдельная функция, которую я использую в некоторых своих программах. Никто не использует promisify и await/async в этом посте, поэтому я решил поделиться.

const isDirectory = async path => {
  try {
    return (await require('util').promisify(require('fs').lstat)(
      path
    )).isDirectory()
  } catch (e) {
    return false // or custom the error
  }
}

Примечание: я не использую require('fs').promises; потому что он был экспериментальным в течение одного года, а не полагаться на него.