fs.stat(): Thám tử file của Node.js - Gen Z cần biết!
Nodejs

fs.stat(): Thám tử file của Node.js - Gen Z cần biết!

Author

Admin System

@root

Ngày xuất bản

20 Mar, 2026

Lượt xem

2 Lượt

"fs.stat()"

Chào các "coder nhí" năng động của Gen Z! Hôm nay, anh Creyt sẽ giới thiệu cho mấy đứa một công cụ cực kỳ hữu ích trong Node.js, giúp mấy đứa "thám hiểm" thế giới file và thư mục một cách chuyên nghiệp: đó chính là fs.stat(). Nghe có vẻ khô khan nhưng tin anh đi, nó "ngầu" hơn mấy đứa tưởng đấy!

fs.stat() là gì mà "hot" thế?

"Mấy đứa cứ hình dung thế này: mỗi file hay thư mục trên máy tính của chúng ta đều có một "căn cước công dân" riêng, chứa đầy đủ thông tin cá nhân như tên, ngày sinh, chiều cao, cân nặng... À nhầm, ý anh là tên, kích thước, ngày tạo, ngày sửa đổi, và quan trọng nhất là nó là "file" hay "folder"." fs.stat() chính là "cảnh sát điều tra" giúp chúng ta đọc được cái "căn cước" đó.

Nói một cách "code-ese" hơn, fs.stat() trong module fs (File System) của Node.js dùng để lấy thông tin metadata của một file hoặc thư mục. Nó không đọc nội dung file đâu nhé, mà chỉ quan tâm đến các thuộc tính bên ngoài của nó thôi. Như kiểu mấy đứa check info crush trước khi inbox vậy đó: xem ảnh đại diện, status, ngày sinh, chứ đâu có đọc tin nhắn riêng tư của người ta đâu, đúng không?

Để làm gì? Đơn giản là để "biết người biết ta". Trước khi mấy đứa định mở một file, xóa nó, hay copy nó đi đâu đó, mấy đứa cần biết:

  • File đó có thực sự tồn tại không?
  • Nó là một file hay một thư mục?
  • Kích thước của nó bao nhiêu? Có vượt quá giới hạn cho phép không?
  • Nó được tạo ra khi nào? Sửa đổi lần cuối lúc nào?

Có thông tin này trong tay, mấy đứa sẽ tránh được hàng tá lỗi vặt và làm cho code của mình "cứng cáp" hơn nhiều.

Code Ví Dụ: "Bóc phốt" file với fs.stat()

Trong Node.js hiện đại, anh Creyt khuyên mấy đứa nên dùng phiên bản Promise-based của fs để code sạch sẽ và dễ đọc hơn, đặc biệt khi làm việc với các tác vụ bất đồng bộ. Đây là cách "bóc phốt" một file:

const fs = require('fs').promises; // Import phiên bản Promise của fs
const path = require('path');

async function getFileInfo(filePath) {
    try {
        const stats = await fs.stat(filePath); // Dùng await để chờ kết quả

        console.log(`--- Thông tin File/Thư mục: ${filePath} ---`);
        console.log(`Kích thước: ${stats.size} bytes`);
        console.log(`Là file? ${stats.isFile()}`);
        console.log(`Là thư mục? ${stats.isDirectory()}`);
        console.log(`Thời gian tạo: ${stats.birthtime.toLocaleString()}`);
        console.log(`Thời gian sửa đổi cuối: ${stats.mtime.toLocaleString()}`);
        console.log(`Thời gian truy cập cuối: ${stats.atime.toLocaleString()}`);
        console.log(`Thời gian thay đổi inode: ${stats.ctime.toLocaleString()}`);

        if (stats.isFile()) {
            console.log(`Đây là một file.`);
        } else if (stats.isDirectory()) {
            console.log(`Đây là một thư mục.`);
        } else {
            console.log(`Loại khác (ví dụ: symbolic link, pipe...).`);
        }

        return stats;

    } catch (error) {
        if (error.code === 'ENOENT') {
            console.error(`Lỗi: Không tìm thấy file hoặc thư mục tại đường dẫn: ${filePath}`);
        } else {
            console.error(`Lỗi khi lấy thông tin cho ${filePath}:`, error.message);
        }
        return null;
    }
}

// Tạo một file tạm để thử nghiệm (nếu chưa có)
fs.writeFile('my_test_file.txt', 'Hello Gen Z, this is a test file!')
    .then(() => {
        console.log('Đã tạo file my_test_file.txt.');
        return getFileInfo('my_test_file.txt');
    })
    .then(() => getFileInfo('.')) // Lấy thông tin của thư mục hiện tại
    .then(() => getFileInfo('non_existent_file.txt')) // Thử với file không tồn tại
    .catch(err => console.error('Lỗi chung:', err.message));

Giải thích sơ bộ cái stats object mà fs.stat() trả về:

Nó giống như một "bộ hồ sơ" đầy đủ, mấy đứa có thể truy cập các thuộc tính sau:

  • stats.isFile(): Trả về true nếu đó là một file thông thường.
  • stats.isDirectory(): Trả về true nếu đó là một thư mục.
  • stats.size: Kích thước của file/thư mục (tính bằng byte).
  • stats.birthtime: Thời gian tạo file/thư mục (đối tượng Date).
  • stats.mtime: Thời gian sửa đổi nội dung cuối cùng (modification time).
  • stats.atime: Thời gian truy cập cuối cùng (access time).
  • stats.ctime: Thời gian thay đổi trạng thái (change time, ví dụ: quyền truy cập, chủ sở hữu).
Illustration

Mẹo của "thám tử" Creyt (Best Practices)

  1. Luôn dùng Async: Mấy đứa nhớ nhé, Node.js sinh ra là để xử lý bất đồng bộ (non-blocking I/O). Vì vậy, hãy luôn luôn dùng fs.promises.stat() (với async/await) hoặc fs.stat() (với callback) thay vì fs.statSync(). Dùng Sync chỉ khi mấy đứa biết chắc chắn là mình đang ở trong một script CLI đơn giản và không muốn block cả ứng dụng của mình.
  2. "Đừng tin ai cả, hãy stat trước!": Giống như khi mấy đứa muốn tải ảnh lên mạng, mấy đứa phải kiểm tra xem nó có đúng định dạng không, kích thước có quá lớn không. Tương tự, trước khi xử lý bất kỳ file nào, hãy dùng fs.stat() để kiểm tra sự tồn tại, loại và các thuộc tính khác. Tránh được lỗi ENOENT (Error NO ENTry - không tìm thấy) hoặc các lỗi khác do xử lý sai loại file.
  3. Xử lý lỗi "thanh lịch": Luôn bao bọc lời gọi fs.stat() trong try...catch (với async/await) hoặc kiểm tra error trong callback. File không tồn tại là lỗi thường gặp nhất, và mấy đứa cần có kế hoạch xử lý nó.

Ứng dụng thực tế của fs.stat() (không phải chỉ trên lý thuyết)

"Mấy đứa nghĩ xem, cái gì mà "thám tử" fs.stat() có thể làm được trong thế giới thực?" Nhiều lắm chứ!

  • Hệ thống quản lý file (File Explorer, Google Drive, Dropbox): Khi mấy đứa mở File Explorer trên Windows hay Finder trên macOS, nó liên tục dùng các chức năng tương tự fs.stat() để hiển thị tên file, kích thước, ngày sửa đổi của từng file/thư mục. Các dịch vụ lưu trữ đám mây cũng dựa vào đó để đồng bộ hóa, kiểm tra phiên bản file.
  • Các công cụ Build (Webpack, Gulp, Vite): Khi mấy đứa code frontend, các công cụ này sẽ theo dõi sự thay đổi của file (mtime) để biết khi nào cần biên dịch lại code, tối ưu hóa hiệu suất build.
  • Server tải file/upload file: Trước khi cho người dùng tải một file lên, server có thể dùng fs.stat() để kiểm tra kích thước file tạm thời, đảm bảo nó không vượt quá giới hạn cho phép, tránh làm sập server vì quá tải.
  • Content Management Systems (CMS) như WordPress, Strapi: Khi mấy đứa upload ảnh, video, CMS sẽ kiểm tra kích thước, loại file, và thậm chí cả mtime để quản lý phiên bản của media đó.

Thử nghiệm và Nên dùng cho Case nào?

"Hồi xưa, anh Creyt cũng từng 'ngây thơ' dùng fs.statSync() trong một script nhỏ để duyệt qua hàng ngàn file và resize ảnh. Kết quả là script chạy chậm như rùa bò, block cả tiến trình vì nó phải chờ từng file một. Từ đó anh mới thấm thía rằng, với Node.js, cứ cái gì liên quan đến I/O (input/output) thì phải dùng bất đồng bộ mới là chân ái!"

Vậy, nên dùng fs.stat() cho những trường hợp nào?

  • Kiểm tra sự tồn tại: Đảm bảo một file hay thư mục có tồn tại trước khi thực hiện các thao tác khác lên nó.
  • Phân loại: Xác định xem một đường dẫn cụ thể trỏ đến một file hay một thư mục. Rất hữu ích khi mấy đứa muốn duyệt qua các thư mục con hoặc xử lý riêng từng loại.
  • Kiểm tra kích thước: Ví dụ, trước khi đọc toàn bộ nội dung của một file lớn vào bộ nhớ, mấy đứa có thể kiểm tra kích thước của nó để tránh tràn RAM.
  • Kiểm tra thời gian: Dùng mtime để tạo logic caching, chỉ tải lại file nếu nó đã được sửa đổi. Hoặc dùng birthtime để sắp xếp file theo thời gian tạo.

fs.stat() giống như một "người gác cổng" thông minh, giúp mấy đứa có được cái nhìn tổng quan về "khách" (file/thư mục) trước khi quyết định cho nó vào nhà (xử lý). Nắm vững nó, mấy đứa sẽ viết được những ứng dụng Node.js an toàn và hiệu quả hơn rất nhiều!

Thuộc Series: Nodejs

Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!

#tech #cyberpunk #laravel
Chỉnh sửa bài viết

Bình luận (0)

Vui lòng Đăng Nhập để Bình luận

Hỗ trợ Markdown cơ bản
Nguyễn Văn A
1 ngày trước

Tính năng này đỉnh quá ad ơi, chờ mãi mới thấy một blog Tiếng Việt có UI/UX xịn như vầy!