Node.js перевіряє, чи шлях - це файл чи каталог


380

Я не можу отримати результати пошуку, які пояснюють, як це зробити.

Все, що я хочу зробити, - це вміти знати, чи заданий шлях - це файл чи каталог (папка).

Відповіді:


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

ПРИМІТКА:

Вище рішення буде якщо; наприклад, існує або не існуєthrowErrorfiledirectory

Якщо ви хочете, trueчи falseпідхід, спробуйте, fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();як згадував Йосиф у коментарях нижче.


18
Зауважте, що асинхронна версія, як правило, бажана, якщо ви дбаєте про загальну ефективність програми.
AlexMA

45
Майте на увазі, що якщо каталог або файл не існує, ви отримаєте помилку назад.
Етан Мік

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

Майте на увазі, що якщо файл або каталог не існує, він викине виняток, який потрібно виловити, інакше це призведе до ненормального виходу.
Сергій Кузнєцов

59

Оновлення: 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:

При використанні синхронної форми будь-які винятки одразу ж кидаються. Ви можете використовувати спробувати / 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>формату, просто подивіться на ім’я.

Очевидно, що якщо ви шукаєте файл без імені, вам потрібно буде натиснути на файлову систему, щоб бути впевненим. Але тримайте це просто, поки вам не знадобиться складніше.

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.