"Hầu hết mọi ứng dụng đều phải đọc hoặc ghi dữ liệu. Trong Node.js, module
fschính là cây cầu giúp chương trình giao tiếp với hệ thống tệp của máy tính."
🎯 Mục tiêu bài học
Sau bài này bạn sẽ:
Hiểu module fs là gì.
Biết đọc và ghi file.
Tạo, sao chép, đổi tên và xóa file.
Tạo và xóa thư mục.
Phân biệt Sync, Callback và Promise.
Biết khi nào nên dùng từng cách.
File System (fs) là gì?
fs (File System) là module có sẵn của Node.js.
Nó cho phép chương trình:
Đọc file
Ghi file
Tạo file
Xóa file
Sao chép file
Đổi tên file
Tạo thư mục
Đọc danh sách thư mục
Không cần cài đặt thêm.
Import fs
ES Module
import fs from "node:fs";
Hoặc
import { promises as fs } from "node:fs";
CommonJS
const fs = require("fs");
Trong khóa học này chúng ta sẽ ưu tiên ES Module.
Cấu trúc dự án
basic/
│
├── app.js
├── data.txt
└── package.json
Nội dung file:
Xin chào Node.js!
Đọc file (Sync)
import fs from "node:fs";
const data = fs.readFileSync("data.txt", "utf8");
console.log(data);
Kết quả
Xin chào Node.js!
readFileSync()
Ý nghĩa:
Đọc file
Chương trình sẽ dừng lại cho đến khi đọc xong.
Đọc file
↓
Chờ...
↓
Có dữ liệu
↓
Tiếp tục chạy
Đây gọi là Synchronous.
Ghi chú: xuất data ngoài hàm
Đọc file (Callback)
import fs from "node:fs";
fs.readFile("data.txt", "utf8", (err, data) => {
if (err) {
console.log(err);
return;
}
console.log(data);
});
Kết quả
Xin chào Node.js!
Node sẽ:
tiếp tục làm việc khác
khi đọc xong mới gọi callback
Đây là Asynchronous.
Ghi chú: xuất data ngay trong hàm.
Đọc file bằng Promise
import { promises as fs } from "node:fs";
const data = await fs.readFile("data.txt", "utf8");
console.log(data);
Đây là cách hiện đại nhất.
Ghi chú: xuất data ngoài hàm giống cách 1 nhưng có thêm chữ await
Ghi file
import fs from "node:fs";
fs.writeFileSync("hello.txt", "Hello Node.js");
Sau khi chạy
hello.txt
được tạo.
Nội dung
Hello Node.js
Ghi file bằng Promise
import { promises as fs } from "node:fs";
await fs.writeFile(
"hello.txt",
"Xin chào Node.js"
);
Ghi đè hay ghi thêm?
Mặc định
writeFile()
sẽ ghi đè.
Ví dụ
File cũ
ABC
Ghi
await fs.writeFile(
"hello.txt",
"XYZ"
);
Kết quả
XYZ
Ghi nối tiếp (Append)
import { promises as fs } from "node:fs";
await fs.appendFile(
"hello.txt",
"\nDòng mới"
);
Kết quả
Hello Node.js
Dòng mới
Kiểm tra file tồn tại
import fs from "node:fs";
console.log(
fs.existsSync("hello.txt")
);
Kết quả
true
Đổi tên file
import fs from "node:fs";
fs.renameSync(
"hello.txt",
"node.txt"
);
Sao chép file
import fs from "node:fs";
fs.copyFileSync(
"node.txt",
"backup.txt"
);
Xóa file
import fs from "node:fs";
fs.unlinkSync("backup.txt");
Tạo thư mục
import fs from "node:fs";
fs.mkdirSync("images");
Sau khi chạy
images/
được tạo.
Tạo nhiều cấp thư mục
fs.mkdirSync(
"public/uploads/images",
{
recursive: true
}
);
Node sẽ tự tạo:
public/
uploads/
images/
Đọc thư mục
import fs from "node:fs";
const files =
fs.readdirSync("./");
console.log(files);
Ví dụ
[
'node_modules',
'app.js',
'data.txt',
'package.json'
]
Xóa thư mục
import fs from "node:fs";
fs.rmSync(
"images",
{
recursive: true
}
);
Thông tin file
import fs from "node:fs";
const stat =
fs.statSync("data.txt");
console.log(stat.size);
Ví dụ
15
Một số thuộc tính hữu ích:
| Thuộc tính | Ý nghĩa |
|---|---|
| size | Kích thước |
| isFile() | Có phải file |
| isDirectory() | Có phải thư mục |
| mtime | Thời gian sửa cuối |
Ví dụ
console.log(stat.isFile());
console.log(stat.isDirectory());
Sync và Async khác nhau thế nào?
Sync
const data =
fs.readFileSync("data.txt");
Node phải chờ.
Đọc file
↓
Chờ
↓
Hoàn thành
↓
Tiếp tục
Ưu điểm
Dễ hiểu
Dễ debug
Nhược điểm
Chặn chương trình
Async
await fs.readFile(
"data.txt"
);
Node không cần chờ.
Đọc file
↓
Làm việc khác
↓
Có dữ liệu
↓
Tiếp tục xử lý
Ưu điểm
Hiệu năng tốt
Phù hợp Server
Khi nào dùng Sync?
Sync phù hợp:
Script nhỏ
Tool chạy một lần
Học tập
CLI đơn giản
Ví dụ
const config =
fs.readFileSync(
"config.json",
"utf8"
);
Khi nào dùng Async?
Nên dùng:
Web Server
REST API
Upload file
Express
Dự án thực tế
Đây cũng là cách bạn sẽ sử dụng trong phần lớn các bài học tiếp theo.
Ví dụ thực tế
Tạo file log
import { promises as fs } from "node:fs";
await fs.appendFile(
"log.txt",
"Đăng nhập thành công\n"
);
Mỗi lần chạy
Đăng nhập thành công
Đăng nhập thành công
Đăng nhập thành công
được thêm vào cuối file.
Đây là cách rất nhiều ứng dụng ghi nhật ký hoạt động (log) trước khi sử dụng các thư viện chuyên dụng.
Những lỗi thường gặp
Sai đường dẫn
ENOENT
Nghĩa là
Không tìm thấy file hoặc thư mục.
Đọc file chưa tồn tại
await fs.readFile("abc.txt");
Lỗi
ENOENT
Hãy kiểm tra trước:
import fs from "node:fs";
if (fs.existsSync("abc.txt")) {
console.log("Có file");
}
Quên encoding
await fs.readFile("data.txt");
Kết quả
<Buffer ...>
Đúng phải là
await fs.readFile(
"data.txt",
"utf8"
);
Tổng kết
Qua bài học này, bạn đã biết cách sử dụng module File System (fs) để làm việc với tệp và thư mục trong Node.js. Bạn đã thực hành các thao tác phổ biến như đọc, ghi, sao chép, đổi tên và xóa file; tạo và quản lý thư mục; đồng thời hiểu sự khác biệt giữa các API Sync, Callback và Promise.
Đây là một trong những module cốt lõi của Node.js và sẽ được sử dụng rất nhiều khi xây dựng ứng dụng thực tế, từ xử lý tệp cấu hình, ghi log cho đến upload và quản lý dữ liệu.
Bài tiếp theo
👉 Bài 07 — Path
Bạn sẽ học:
Module
pathlà gì.Làm việc với đường dẫn trên Windows và Linux.
join(),resolve(),basename(),dirname(),extname().Vì sao không nên tự nối đường dẫn bằng dấu
/.Kết hợp
pathvàfsđể xây dựng các ứng dụng xử lý tệp an toàn và đa nền tảng.




Không có nhận xét nào:
Đăng nhận xét