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

บันทึก:

การแก้ปัญหาข้างต้นจะthrowเป็นErrorถ้า; สำหรับอดีตfileหรือdirectoryไม่มีอยู่

หากคุณต้องการtrueหรือfalseวิธีการลองfs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();โจเซฟดังกล่าวในความคิดเห็นด้านล่าง


18
โปรดทราบว่าโดยทั่วไปแล้วเวอร์ชันอะซิงโครนัสจะดีกว่าหากคุณสนใจเกี่ยวกับประสิทธิภาพของแอปทั่วไป
AlexMA

45
โปรดทราบว่าหากไม่มีไดเรกทอรีหรือไฟล์อยู่คุณจะได้รับข้อผิดพลาดกลับมา
Ethan Mick

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

โปรดทราบว่าหากไม่มีไฟล์หรือไดเรกทอรีอยู่จะมีข้อยกเว้นที่จำเป็นต้องถูกจับมิฉะนั้นจะทำให้เกิดการผิดปกติ
Sergey Kuznetsov

59

อัปเดต: Node.Js> = 10

เราสามารถใช้fs.promises API ใหม่

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

หมายเหตุเมื่อใช้ synchronous API:

เมื่อใช้รูปแบบซิงโครนัสจะมีการโยนข้อยกเว้นใด ๆ ทันที คุณสามารถใช้ลอง / จับเพื่อจัดการข้อยกเว้นหรืออนุญาตให้ฟองเพิ่มขึ้น

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โมดูลของโหนดได้ทั้งนี้ขึ้นอยู่กับความต้องการของคุณ

คุณอาจไม่สามารถเข้าถึงระบบไฟล์ (เช่นยังไม่ได้สร้างไฟล์) และ tbh คุณอาจต้องการหลีกเลี่ยงการชนระบบไฟล์เว้นแต่คุณจำเป็นต้องมีการตรวจสอบความถูกต้องเป็นพิเศษ หากคุณสามารถสันนิษฐานได้ว่าสิ่งที่คุณกำลังตรวจสอบสำหรับ.<extname>รูปแบบดังต่อไปนี้เพียงแค่ดูที่ชื่อ

เห็นได้ชัดว่าหากคุณกำลังมองหาไฟล์ที่ไม่มีชื่อคุณจะต้องกดระบบไฟล์เพื่อให้แน่ใจว่า แต่ให้เรียบง่ายจนกว่าคุณจะต้องการความซับซ้อนมากขึ้น

const path = require('path');

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

2
เห็นได้ชัดว่าสิ่งนี้จะไม่ทำงานในทุกสถานการณ์ แต่จะเร็วกว่าและง่ายกว่าคำตอบอื่น ๆ หากคุณสามารถตั้งสมมติฐานที่จำเป็นได้
electrovir

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;เพราะทดลองมาหนึ่งปีแล้วดีกว่าอย่าพึ่งใช้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.