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

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

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

300
26 марта '13 в 9:32
источник поделиться
7 ответов

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()
477
26 марта '13 в 9:36
источник

Обновление: 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
   }
}
40
30 апр. '17 в 3:42
источник

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

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;
    }
}
8
29 нояб. '18 в 3:31
источник

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

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

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

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

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

const path = require('path');

function isFile(pathItem) {
  return !!path.extname(pathItem);
}
1
19 марта '19 в 23:57
источник
 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();
   });

 }
0
24 янв. '19 в 11:05
источник

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

0
04 апр. '19 в 11:16
источник

Посмотрите другие вопросы по меткам или Задайте вопрос