Node.js yolun dosya veya dizin olup olmadığını kontrol edin


380

Bunun nasıl yapılacağını açıklayan herhangi bir arama sonucu alamıyorum.

Tek yapmak istediğim belirli bir yolun bir dosya mı yoksa bir dizin mi (klasör) olup olmadığını bilmek.

Yanıtlar:


609

fs.lstatSync(path_string).isDirectory()söylemeliyim. Gönderen docs :

Fs.stat () ve fs.lstat () öğelerinden döndürülen nesneler bu türdedir.

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

NOT:

Çözelti, yukarıda olacak throwbir Errorvarsa; örneğin, fileveya directoryyoktur.

Bir trueveya falseyaklaşım istiyorsanız , fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();Joseph tarafından aşağıdaki yorumlarda belirtildiği gibi deneyin .


18
Genel uygulama performansını önemsiyorsanız, eşzamansız sürümün genellikle tercih edildiğini unutmayın.
AlexMA

45
Dizin veya dosya yoksa, geri bir hata alacağınızı unutmayın.
Ethan Mick

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

Dosya veya dizin yoksa, yakalanması gereken bir istisna atacağını, aksi takdirde anormal çıkışa neden olacağını unutmayın.
Sergey Kuznetsov

59

Güncelleme: Düğüm.Js> = 10

Yeni fs.promises API'sını kullanabiliriz

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

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

Herhangi bir Node.Js sürümü

Yolun bir dosya mı yoksa eşzamansız olarak bir dizin mi olduğunu, düğümde önerilen yaklaşım olan yöntemi nasıl algılayacağınız aşağıda açıklanmıştır . fs.lstat kullanma

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()}`);
});

Eşzamanlı API'yı kullanırken dikkat edin:

Senkronize form kullanıldığında, herhangi bir istisna hemen atılır. İstisnaları işlemek için dene / yakala'yı kullanabilir veya kabarmalarına izin verebilirsiniz.

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

Bu, Mart 2020 itibariyle hala deneysel kabul ediliyor mu? Nereyi görmek için bakabiliriz? - Hata! Yukarıdaki bağlantıyı tıkladığımda görüyorum ki artık kararlı (artık deneysel değil).
alfreema

20

Cidden, soru beş yıl var ve hoş bir cephe yok mu?

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

İhtiyaçlarınıza bağlı olarak, muhtemelen düğümün pathmodülüne güvenebilirsiniz .

Dosya sistemine vuramayabilirsiniz (örn. Dosya henüz oluşturulmamıştır) ve ekstra validasyona gerçekten ihtiyacınız olmadıkça muhtemelen dosya sistemine çarpmaktan kaçınmak isteyebilirsiniz. Kontrol ettiğiniz şeyin .<extname>biçimi izlediğini varsayabilirseniz, sadece isme bakın.

Açıkçası, bir ek ad içermeyen bir dosya arıyorsanız, emin olmak için dosya sistemine basmanız gerekir. Ancak daha karmaşık olana kadar basit tutun.

const path = require('path');

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

2
Açıkçası bu her durumda işe yaramaz, ancak gerekli varsayımları yapabiliyorsanız diğer yanıtlardan çok daha hızlı ve kolaydır.
electrovir

1

Yukarıdaki yanıtlar, bir dosya sisteminin dosya veya dizin olan bir yol içerip içermediğini kontrol eder. Ancak belirli bir yolun tek başına bir dosya veya dizin olup olmadığını tanımlamaz.

Cevap dizin tabanlı yolları "/" kullanarak tanımlamaktır. gibi -> "/ c / dos / run /." <- sondaki nokta.

Henüz yazılmamış bir dizin veya dosyanın yolu gibi. Veya farklı bir bilgisayardan bir yol. Veya aynı ada sahip bir dosyanın ve dizinin bulunduğu bir yol.

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

Düğüm sürümü: v11.10.0 - Şub 2019

Son düşünce: Neden dosya sistemine çarptı?


1

İşte kullandığım bir fonksiyon. Kimse bu yazıdan faydalanmıyor promisifyve await/asyncbu özelliği kullanmıyor, bu yüzden paylaşacağımı düşündüm.

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

Not: Kullanmıyorum require('fs').promises;çünkü bir yıldır deneysel oldu, güvenmemek daha iyi.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.