Node.js memeriksa apakah path adalah file atau direktori


381

Sepertinya saya tidak dapat memperoleh hasil pencarian yang menjelaskan cara melakukan ini.

Yang ingin saya lakukan adalah mengetahui apakah path yang diberikan adalah file atau direktori (folder).

Jawaban:


610

fs.lstatSync(path_string).isDirectory()harus memberitahumu. Dari dokumen :

Objek yang dikembalikan dari fs.stat () dan fs.lstat () adalah dari jenis ini.

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

CATATAN:

The atas solusi akan throwsebuah Errorjika; misalnya, fileatau directorytidak ada.

Jika Anda menginginkan trueatau falsemendekati, cobalah fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();seperti yang disebutkan oleh Joseph dalam komentar di bawah.


18
Perhatikan bahwa versi asinkron biasanya lebih disukai jika Anda peduli dengan kinerja aplikasi umum.
AlexMA

45
Perlu diingat bahwa jika direktori atau file tidak ada, maka Anda akan mendapatkan kesalahan kembali.
Ethan Mick

9
let isDirExists = fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();
Jossef Harush

Perlu diingat bahwa jika file atau direktori tidak ada, ia akan membuang pengecualian yang perlu ditangkap jika tidak maka akan menyebabkan abnormal exit.
Sergey Kuznetsov

59

Pembaruan: Node.Js> = 10

Kita dapat menggunakan API fs.promises baru

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

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

Versi Node.Js apa pun

Inilah cara Anda akan mendeteksi jika jalur adalah file atau direktori secara tidak sinkron , yang merupakan pendekatan yang disarankan dalam simpul. menggunakan 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()}`);
});

Catatan saat menggunakan API sinkron:

Saat menggunakan formulir sinkron, pengecualian apa pun segera dilemparkan. Anda dapat menggunakan try / catch untuk menangani pengecualian atau membiarkannya muncul.

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

Apakah ini masih dianggap eksperimental pada Maret 2020? Di mana kita bisa melihat? - Ups, saya melihat ketika saya mengklik tautan di atas bahwa itu sekarang stabil (yang berarti tidak lagi eksperimental).
alfreema

20

Serius, pertanyaan ada lima tahun dan tidak ada fasad yang bagus?

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

Tergantung pada kebutuhan Anda, Anda mungkin dapat mengandalkan node path modul .

Anda mungkin tidak dapat menekan sistem file (misalnya file belum dibuat) dan tbh Anda mungkin ingin menghindari memukul sistem file kecuali Anda benar-benar membutuhkan validasi tambahan. Jika Anda dapat membuat asumsi bahwa apa yang Anda periksa mengikuti .<extname>format, lihat saja namanya.

Tentunya jika Anda mencari file tanpa nama samaran Anda harus menekan sistem file untuk memastikan. Tetapi tetap sederhana sampai Anda perlu lebih rumit.

const path = require('path');

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

2
Jelas ini tidak akan bekerja dalam semua situasi tetapi jauh lebih cepat dan lebih mudah daripada jawaban lain jika Anda dapat membuat asumsi yang diperlukan.
electrovir

1

Jawaban di atas memeriksa apakah sistem file berisi jalur yang merupakan file atau direktori. Tapi itu tidak mengidentifikasi apakah jalur yang diberikan sendiri adalah file atau direktori.

Jawabannya adalah untuk mengidentifikasi jalur berbasis direktori menggunakan "/." seperti -> "/ c / dos / run /." <- periode trailing.

Seperti jalur direktori atau file yang belum ditulis. Atau jalur dari komputer yang berbeda. Atau jalur tempat file dan direktori dengan nama yang sama ada.

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

Versi simpul: v11.10.0 - Feb 2019

Pikiran terakhir: Mengapa memukul sistem file?


1

Inilah fungsi yang saya gunakan. Tidak ada yang memanfaatkan promisifydan await/asyncfitur dalam posting ini jadi saya pikir saya akan berbagi.

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

Catatan: Saya tidak menggunakan require('fs').promises;karena sudah eksperimental selama satu tahun sekarang, lebih baik jangan mengandalkannya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.