Node.js kiểm tra xem đường dẫn là tệp hoặc thư mục


380

Tôi dường như không thể nhận được bất kỳ kết quả tìm kiếm nào giải thích cách làm điều này.

Tất cả những gì tôi muốn làm là có thể biết liệu một đường dẫn cụ thể là một tệp hoặc một thư mục (thư mục).

Câu trả lời:


609

fs.lstatSync(path_string).isDirectory()nên nói với bạn Từ các tài liệu :

Các đối tượng được trả về từ fs.stat () và fs.lstat () thuộc loại này.

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

GHI CHÚ:

Các giải pháp trên sẽ throwmột Errornếu; cho ex, các filehoặc directorykhông tồn tại.

Nếu bạn muốn một truehoặc falsetiếp cận, hãy thử fs.existsSync(dirPath) && fs.lstatSync(dirPath).isDirectory();như được đề cập bởi Joseph trong các ý kiến ​​dưới đây.


18
Lưu ý rằng phiên bản không đồng bộ thường thích hợp hơn nếu bạn quan tâm đến hiệu suất ứng dụng chung.
AlexMA

45
Hãy nhớ rằng nếu thư mục hoặc tệp không tồn tại, thì bạn sẽ gặp lỗi.
Ethan Mick

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

Hãy nhớ rằng nếu tập tin hoặc thư mục không tồn tại, nó sẽ ném ngoại lệ cần được bắt nếu không nó sẽ gây ra lối thoát bất thường.
Serge Kuznetsov

59

Cập nhật: Node.Js> = 10

Chúng tôi có thể sử dụng API fs.promises mới

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

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

Bất kỳ phiên bản Node.Js

Đây là cách bạn sẽ phát hiện nếu một đường dẫn là một tệp hoặc một thư mục không đồng bộ , đó là cách tiếp cận được đề xuất trong nút. sử dụng 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()}`);
});

Lưu ý khi sử dụng API đồng bộ:

Khi sử dụng hình thức đồng bộ, mọi ngoại lệ sẽ được đưa ra ngay lập tức. Bạn có thể sử dụng thử / bắt để xử lý các trường hợp ngoại lệ hoặc cho phép chúng nổi bong bóng.

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

Đây có còn được coi là thử nghiệm vào tháng 3 năm 2020 không? Chúng ta có thể nhìn vào đâu để xem? - Rất tiếc tôi thấy khi tôi nhấp vào liên kết ở trên mà giờ đây nó đã ổn định (ngụ ý không còn thử nghiệm nữa).
alfreema

20

Nghiêm túc mà nói, câu hỏi tồn tại năm năm và không có mặt tiền đẹp?

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

Tùy thuộc vào nhu cầu của bạn, có lẽ bạn có thể dựa vào pathmô-đun của nút .

Bạn có thể không thể truy cập hệ thống tệp (ví dụ: tệp chưa được tạo) và bạn có thể muốn tránh nhấn hệ thống tệp trừ khi bạn thực sự cần xác thực thêm. Nếu bạn có thể đưa ra giả định rằng những gì bạn đang kiểm tra .<extname>định dạng sau , chỉ cần nhìn vào tên.

Rõ ràng nếu bạn đang tìm kiếm một tệp không có tên mở rộng, bạn sẽ cần phải nhấn hệ thống tệp để chắc chắn. Nhưng giữ cho nó đơn giản cho đến khi bạn cần phức tạp hơn.

const path = require('path');

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

2
Rõ ràng điều này sẽ không hoạt động trong mọi tình huống nhưng nó nhanh hơn và dễ dàng hơn nhiều so với các câu trả lời khác nếu bạn có thể đưa ra các giả định cần thiết.
bầu chọn

1

Các câu trả lời ở trên kiểm tra xem một hệ thống tập tin có chứa một đường dẫn là một tập tin hoặc thư mục. Nhưng nó không xác định nếu một đường dẫn nhất định là một tệp hoặc thư mục.

Câu trả lời là xác định các đường dẫn dựa trên thư mục bằng cách sử dụng "/." như -> "/ c / dos / run /." <- thời gian kéo dài.

Giống như một đường dẫn của một thư mục hoặc tập tin chưa được viết. Hoặc một đường dẫn từ một máy tính khác. Hoặc một đường dẫn tồn tại cả tệp và thư mục cùng tên.

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

Phiên bản nút: v11.10.0 - Tháng 2 năm 2019

Suy nghĩ cuối cùng: Tại sao thậm chí nhấn hệ thống tập tin?


1

Đây là một chức năng mà tôi sử dụng. Không ai đang sử dụng promisifyawait/asynctính năng trong bài viết này vì vậy tôi nghĩ rằng tôi sẽ chia sẻ.

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

Lưu ý: Tôi không sử dụng require('fs').promises;vì nó đã được thử nghiệm trong một năm nay, tốt hơn là không nên dựa vào nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.