
Chào các dân chơi Node.js! Anh Creyt lại lên sóng đây. Hôm nay, chúng ta sẽ cùng "mổ xẻ" một "thám tử" siêu đẳng trong thế giới file system của Node.js: fs.statSync(). Nghe cái tên có vẻ "hàn lâm" nhưng thực ra nó là một công cụ cực kỳ hữu ích, đặc biệt khi bạn cần "xem mặt đặt tên" một file hay thư mục nào đó ngay lập tức.
fs.statSync() là gì? Để làm gì?
Đầu tiên, hãy tưởng tượng thế này: bạn đang lướt TikTok, thấy một video hay ho và muốn biết "hồ sơ" của nó – nặng bao nhiêu, đăng từ bao giờ, có phải là video hay ảnh không? Trong thế giới của Node.js, khi bạn cần "soi" một file hay thư mục, fs.statSync() chính là "công cụ xem thông tin" nhanh gọn lẹ của bạn.
Nói một cách "chuẩn chỉnh" hơn, fs.statSync() là một phương thức đồng bộ (synchronous) thuộc module fs (File System) của Node.js. Nhiệm vụ của nó là đọc và trả về thông tin metadata chi tiết về một đường dẫn file hoặc thư mục cụ thể. "Metadata" ở đây chính là những thông tin như:
- Kích thước của file (size).
- Loại đối tượng đó là gì (file, thư mục, symbolic link, v.v.) qua các hàm
isFile(),isDirectory(),isSymbolicLink(). - Ngày tạo (birthtime).
- Ngày sửa đổi cuối cùng (mtime).
- Quyền truy cập (mode).
- Và nhiều thông tin khác nữa...
Chữ Sync ở cuối tên hàm cực kỳ quan trọng, nó báo hiệu rằng hàm này sẽ chặn (block) luồng thực thi chính của chương trình cho đến khi nó hoàn thành việc đọc thông tin. Tức là, khi bạn gọi fs.statSync(), chương trình của bạn sẽ "đứng yên chờ đợi" cho đến khi có kết quả trả về, không làm bất cứ việc gì khác. Nghe có vẻ "nguy hiểm" nhưng đôi khi, đó lại là thứ bạn cần!
Code Ví Dụ Minh Hoạ Rõ Ràng
Để các bạn dễ hình dung, anh Creyt đã chuẩn bị một ví dụ "thực chiến" đây. Chúng ta sẽ tạo ra một file và một thư mục ảo, sau đó dùng fs.statSync() để "điều tra" chúng.
const fs = require('fs');
const path = require('path');
// Bước 1: Chuẩn bị "hiện trường" - tạo file và folder giả định để test
const filePath = path.join(__dirname, 'creyt_note.txt');
const dirPath = path.join(__dirname, 'creyt_project_folder');
const nonExistentPath = path.join(__dirname, 'file_khong_ton_tai.txt');
try {
// Ghi một vài dòng vào file creyt_note.txt
fs.writeFileSync(filePath, 'Hello các bạn gen Z! Đây là ghi chú của thầy Creyt.');
// Tạo thư mục creyt_project_folder
fs.mkdirSync(dirPath, { recursive: true });
console.log('--- Đang "điều tra" file creyt_note.txt ---');
const fileStats = fs.statSync(filePath); // "Soi" file
console.log(`Kích thước file: ${fileStats.size} bytes`);
console.log(`Có phải là thư mục?: ${fileStats.isDirectory()}`);
console.log(`Có phải là file?: ${fileStats.isFile()}`);
console.log(`Ngày tạo file: ${fileStats.birthtime}`);
console.log(`Ngày sửa đổi cuối cùng: ${fileStats.mtime}`);
console.log('
--- Đang "điều tra" thư mục creyt_project_folder ---');
const dirStats = fs.statSync(dirPath); // "Soi" thư mục
console.log(`Kích thước thư mục: ${dirStats.size} bytes (lưu ý: trên Linux/macOS, kích thước thư mục rỗng thường là 4096 bytes)`);
console.log(`Có phải là thư mục?: ${dirStats.isDirectory()}`);
console.log(`Có phải là file?: ${dirStats.isFile()}`);
console.log(`Ngày tạo thư mục: ${dirStats.birthtime}`);
console.log(`Ngày sửa đổi cuối cùng: ${dirStats.mtime}`);
console.log('
--- Thử "điều tra" một file không tồn tại (sẽ lỗi) ---');
try {
fs.statSync(nonExistentPath);
} catch (error) {
if (error.code === 'ENOENT') { // ENOENT: Error NO ENTry (file or directory does not exist)
console.error(`Lỗi: "${nonExistentPath}" không tồn tại. Chuẩn bài!`);
} else {
console.error(`Lỗi khác xảy ra: ${error.message}`);
}
}
} catch (err) {
console.error('Có lỗi xảy ra trong quá trình chuẩn bị file/folder hoặc đọc stats:', err);
} finally {
// Bước 3: "Dọn dẹp hiện trường" - xóa file và folder đã tạo
if (fs.existsSync(filePath)) fs.unlinkSync(filePath);
if (fs.existsSync(dirPath)) fs.rmdirSync(dirPath, { recursive: true });
console.log('\nĐã dọn dẹp các file và folder tạm thời.');
}
Khi chạy đoạn code trên, bạn sẽ thấy nó in ra tất tần tật thông tin về creyt_note.txt và creyt_project_folder, từ kích thước cho đến ngày sinh, ngày "tái tạo" cuối cùng. Và đặc biệt, nó sẽ bắt được lỗi khi bạn cố gắng "soi" một file không tồn tại.

Mẹo (Best Practices) & Ghi nhớ từ anh Creyt
- "Sync" là đồng bộ, không phải "Synergy": Nhớ kỹ chữ
Synctrongfs.statSync()nghĩa là nó sẽ block luồng chính. Giống như bạn đang "đứng chờ" kết quả ngay lập tức, không làm việc gì khác được cho đến khi có thông tin. Điều này cực kỳ quan trọng khi bạn code backend! - Thận trọng với
Synctrong ứng dụng lớn: Trong các ứng dụng server (như web API), việc block luồng chính là "tối kỵ". Nó sẽ làm tắc nghẽn các request khác, giống như một con đường đông đúc bị kẹt xe chỉ vì một chiếc xe đang chờ đổ xăng. Thay vào đó, hãy ưu tiên bản bất đồng bộ (asynchronous) làfs.stat()hoặc dùngfs.promises.statvớiasync/awaitđể hệ thống hoạt động mượt mà hơn. - Luôn dùng
try...catch:fs.statSync()sẽ "quăng lỗi" (throw an error) nếu đường dẫn không tồn tại hoặc bạn không có quyền truy cập. Luôn "bọc" nó trongtry...catchđể ứng dụng của bạn không bị "sập nguồn" đột ngột. - Các thuộc tính "vàng":
isDirectory(),isFile(),size,birthtime,mtimelà những "chứng minh thư" cơ bản và thường dùng nhất của mọi file/folder. Nắm chắc chúng là bạn đã có chìa khóa để "đọc vị" mọi thứ rồi.
Ứng dụng thực tế: fs.statSync() "làm được gì"?
fs.statSync() (hoặc phiên bản async của nó) là "người hùng thầm lặng" trong nhiều ứng dụng mà bạn dùng hàng ngày:
- Trình quản lý file (File Manager): Các ứng dụng như Windows Explorer, Finder trên macOS, hoặc các trình quản lý file trên web (như Admin Panel của WordPress) đều dùng thông tin này để hiển thị kích thước, ngày sửa đổi, biểu tượng file/thư mục.
- Kiểm tra file upload: Khi bạn upload ảnh lên Facebook, Instagram, hệ thống backend sẽ dùng
statđể kiểm tra xem đó có thực sự là một file, kích thước có vượt quá giới hạn không trước khi lưu trữ. - Hệ thống cache/build: Các công cụ build như Webpack, Gulp, hay các hệ thống cache thường kiểm tra
mtimecủa file nguồn. Nếumtimethay đổi, họ biết rằng file đã được sửa đổi và cần phải rebuild hoặc invalidate cache. - Hệ thống backup: Các phần mềm backup chỉ sao lưu những file đã thay đổi kể từ lần backup cuối cùng, dựa vào
mtimeđể tối ưu hiệu suất. - Kiểm tra đường dẫn: Đảm bảo đường dẫn người dùng cung cấp là thư mục trước khi thực hiện các thao tác chỉ dành cho thư mục (ví dụ:
rmdirchỉ xóa thư mục).
Thử nghiệm đã từng và Hướng dẫn nên dùng cho case nào
Anh Creyt đã từng "thử nghiệm" và "trải đời" với fs.statSync() rất nhiều. Đây là vài lời khuyên chân thành:
-
Nên dùng
fs.statSync()khi nào?- Script CLI (Command Line Interface) đơn giản: Khi bạn viết các script chạy một lần, không yêu cầu phản hồi ngay lập tức cho nhiều người dùng (ví dụ: script dọn dẹp thư mục, script kiểm tra cấu hình trước khi deploy). Việc block luồng không phải là vấn đề lớn.
- Giai đoạn khởi tạo ứng dụng: Trong các hàm khởi tạo (initialization) của một ứng dụng, khi bạn cần kiểm tra sự tồn tại của file cấu hình ngay lập tức để quyết định cách ứng dụng sẽ chạy. Lúc này, block một chút cũng không sao vì ứng dụng chưa đi vào hoạt động chính thức.
- Trong các bài kiểm tra (Unit Tests): Để thiết lập môi trường test hoặc kiểm tra kết quả sau khi một hàm chạy xong. Tests thường chạy tuần tự, nên
Synclà ổn.
-
Không nên dùng
fs.statSync()khi nào?- Trong ứng dụng Web Server/API Server: Tuyệt đối tránh trong các hàm xử lý request của người dùng (route handlers). Dùng
fs.stat(callback-based) hoặcfs.promises.stat(async/await) để đảm bảo server có thể xử lý nhiều request đồng thời mà không bị treo. - Khi thao tác với số lượng lớn file: Nếu bạn cần xử lý hàng trăm, hàng ngàn file, mỗi lần gọi
statSyncsẽ gây ra độ trễ đáng kể và làm chậm toàn bộ quá trình.
- Trong ứng dụng Web Server/API Server: Tuyệt đối tránh trong các hàm xử lý request của người dùng (route handlers). Dùng
Nhớ nhé, fs.statSync() là một "thám tử" nhanh nhẹn nhưng đôi khi hơi "độc đoán" vì nó bắt bạn phải chờ. Hãy chọn đúng thời điểm để "triệu hồi" nó, và bạn sẽ thấy sức mạnh của nó trong việc quản lý file hệ thống!
Chúc các bạn code vui vẻ và luôn "ngầu" như anh Creyt!
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é!