fs — readFile, writeFile, mkdir, unlink
Muammodan boshlaylik
Brauzerda JavaScript fayl tizimiga tegolmaydi. Bu ataylab qilingan — tasavvur qiling, har qanday sayt sizning kompyuteringizdagi fayllarni o'qisa yoki o'chirsa. Xavfli bo'lardi.
Node.js da bu cheklov yo'q. Siz server tomonda ishlayapsiz — fayllarni o'qish, yozish, papka yaratish, o'chirish hammasi mumkin. fs (file system) moduli aynan shu uchun.
fs moduli nima?
fs — Node.js ning o'rnatilgan moduli. Fayl tizimi bilan ishlash uchun. Alohida o'rnatish shart emas.
const fs = require('fs');
fs modulida har bir operatsiyaning uch xil versiyasi bor. Bu boshida chalkashtirib yuborishi mumkin, shuning uchun tushuntirib o'tamiz.
Uch xil uslub — nima uchun?
Node.js asinxron ishlaydi — bu uning kuchi. Lekin fayl o'qish vaqt oladi: disk sekin, tarmoq sekin. Shu vaqtda Node.js nima qilishi kerak — kutib tursinmi yoki boshqa ishni qilsinmi?
Shuning uchun uch xil yondashuv paydo bo'lgan:
1. Callback uslubi — "fayl o'qib bo'lgach, mana bu funksiyani chaqir". Node.js kutmaydi, boshqa ishni qiladi. Eski, lekin hali keng ishlatiladi.
2. Sync uslubi — "fayl o'qib bo'lguncha hamma narsani to'xtat". Oddiy, lekin server ishlayotganda xavfli — boshqa so'rovlar ham kutib qoladi.
3. fs/promises uslubi — zamonaviy. async/await bilan ishlaydi. Callback ning murakkabligisiz, Sync ning xavfisiz.
// 1. Callback
fs.readFile('file.txt', 'utf8', (err, data) => {
console.log(data);
});
// 2. Sync — bajarilguncha hamma narsa to'xtaydi
const data = fs.readFileSync('file.txt', 'utf8');
// 3. fs/promises — zamonaviy
const fs = require('fs/promises');
const data = await fs.readFile('file.txt', 'utf8');
Hozir callback uslubini o'rganamiz — asosni tushunish uchun. Keyingi darsda fs/promises batafsil ko'riladi.
readFile — fayl o'qish
fs.readFile faylni o'qiydi va tayyor bo'lgach callback ni chaqiradi. Callback har doim ikki argument oladi: err (xato bo'lsa) va data (o'qilgan ma'lumot).
const fs = require('fs');
fs.readFile('hello.txt', 'utf8', (err, data) => {
if (err) {
console.error('Xato:', err.message);
return;
}
console.log(data);
});
Encoding nima uchun kerak?
Disk faylni baytlar ketma-ketligi sifatida saqlaydi. 'utf8' deb aytmasangiz — Node.js bu baytlarni qanday matnга aylantirish kerakligini bilmaydi va xom Buffer qaytaradi.
// Encoding berilmasa:
fs.readFile('hello.txt', (err, data) => {
console.log(data);
// <Buffer 53 61 6c 6f 6d 21> ← xom baytlar, o'qib bo'lmaydi
console.log(data.toString());
// 'Salom!' ← toString() bilan matnга aylantirish mumkin
});
// Encoding berilsa:
fs.readFile('hello.txt', 'utf8', (err, data) => {
console.log(data);
// 'Salom!' ← to'g'ridan-to'g'ri string
});
Matn fayllar uchun 'utf8' bering. Rasm, PDF, video kabi binary fayllar uchun encoding bermang — ular matn emas, baytlar bilan ishlash kerak.
writeFile — fayl yozish
fs.writeFile faylga yozadi. Fayl mavjud bo'lsa — to'liq ustiga yozadi. Mavjud bo'lmasa — yangi yaratadi.
fs.writeFile('output.txt', 'Salom, dunyo!', 'utf8', (err) => {
if (err) {
console.error('Yozishda xato:', err.message);
return;
}
console.log('Fayl yozildi');
});
⚠️
writeFilefaylning eski kontentini to'liq o'chiradi va yangisini yozadi. Eski ma'lumot yo'qoladi. Agar qo'shib yozish kerak bo'lsa —appendFileishlatiladi.
appendFile — qo'shib yozish:
appendFile mavjud faylning oxiriga qo'shib yozadi. Fayl yo'q bo'lsa — yangi yaratadi. Log fayllari uchun ideal.
fs.appendFile('log.txt', 'Yangi qator\n', 'utf8', (err) => {
if (err) console.error(err);
});
// Har chaqirilganda faylning oxiriga qo'shiladi
JSON saqlash — keng tarqalgan amaliyot:
const users = [
{ id: 1, name: 'Ali' },
{ id: 2, name: 'Vali' },
];
fs.writeFile(
'users.json',
JSON.stringify(users, null, 2),
'utf8',
(err) => {
if (err) console.error(err);
}
);
JSON.stringify(users, null, 2) — ikkinchi argument null (replacer, hozir kerak emas), uchinchi argument 2 — chiroyli formatlash uchun bo'sh joy soni.
mkdir — papka yaratish
fs.mkdir yangi papka yaratadi.
fs.mkdir('uploads', (err) => {
if (err) {
console.error(err.message);
return;
}
console.log('Papka yaratildi');
});
Muammo: papka allaqachon mavjud bo'lsa — xato chiqadi:
Error: EEXIST: file already exists, mkdir 'uploads'
Bu tez-tez uchraydigan holat. Yechim — { recursive: true } opsiyasi:
fs.mkdir('uploads/images/2026', { recursive: true }, (err) => {
if (err) console.error(err);
else console.log('Papka(lar) yaratildi');
});
recursive: true ikki narsa qiladi: papka allaqachon mavjud bo'lsa xato chiqarmaydi, va ichma-ich papkalarni ham yaratadi (uploads yo'q bo'lsa ham — hammasi yaratiladi).
readdir — papka ichini o'qish
fs.readdir papka ichidagi fayl va papkalar nomlarini massiv sifatida qaytaradi.
fs.readdir('.', (err, items) => {
if (err) return console.error(err);
console.log(items);
// ['app.js', 'package.json', 'node_modules', 'src', ...]
});
Bu faqat nomlarni beradi — fayl yoki papka ekanini aytmaydi. Farqlash uchun fs.stat kerak:
const path = require('path');
fs.readdir('.', (err, items) => {
if (err) return console.error(err);
items.forEach(item => {
fs.stat(path.join('.', item), (err, stat) => {
if (err) return;
if (stat.isFile()) console.log('Fayl:', item);
if (stat.isDirectory()) console.log('Papka:', item);
});
});
});
stat — fayl haqida ma'lumot
fs.stat fayl yoki papka haqida batafsil ma'lumot beradi: hajmi, yaratilgan vaqti, oxirgi o'zgartirilgan vaqti, fayl yoki papka ekani.
fs.stat('app.js', (err, stat) => {
if (err) {
console.error(err.message);
return;
}
console.log(stat.isFile()); // true
console.log(stat.isDirectory()); // false
console.log(stat.size); // 1024 ← baytda
console.log(stat.mtime); // 2026-05-07T... ← oxirgi o'zgartirilgan vaqt
console.log(stat.birthtime); // 2026-05-01T... ← yaratilgan vaqt
});
unlink — fayl o'chirish
unlink — fayl o'chiradi. Nomi g'alati tuyuladi — bu Unix terminologiyasidan kelgan. Unix da fayllar "link" (havola) sifatida saqlanadi, unlink esa shu havolani o'chiradi.
fs.unlink('temp.txt', (err) => {
if (err) {
console.error(err.message);
// ENOENT: no such file or directory ← fayl yo'q bo'lsa
return;
}
console.log("Fayl o'chirildi");
});
Papka o'chirish:
Bo'sh papkani o'chirish uchun rmdir, ichidagi narsalar bilan birga o'chirish uchun rm:
// Bo'sh papkani o'chirish:
fs.rmdir('empty-folder', (err) => {
if (err) console.error(err);
});
// Ichidagi narsalar bilan birga o'chirish (Node.js 14.14+):
fs.rm('uploads', { recursive: true, force: true }, (err) => {
if (err) console.error(err);
});
// force: true — papka yo'q bo'lsa ham xato chiqarmaydi
rename — nom o'zgartirish va ko'chirish
rename faylning nomini o'zgartiradi yoki boshqa papkaga ko'chiradi. Aslida ikkalasi bir xil narsa — fayl tizimida fayl yo'li o'zgaradi.
// Nom o'zgartirish:
fs.rename('old-name.txt', 'new-name.txt', (err) => {
if (err) console.error(err);
});
// Boshqa papkaga ko'chirish:
fs.rename('uploads/temp.jpg', 'uploads/images/photo.jpg', (err) => {
if (err) console.error(err);
});
⚠️
renamefaqat bir xil disk ichida ishlaydi. Boshqa diskka ko'chirishdaEXDEVxatosi chiqadi. Bunday holdacopyFile+unlinkishlatiladi.
Fayl mavjudligini tekshirish
Ko'pchilik fs.exists ni qidiradi — lekin u deprecated (eskirgan va ishlatilmasligi kerak). To'g'ri usul:
// Xato usul (deprecated):
fs.exists('file.txt', (exists) => { ... }); // ishlatmang
// To'g'ri usul — access bilan:
fs.access('file.txt', fs.constants.F_OK, (err) => {
if (err) {
console.log("Fayl yo'q");
} else {
console.log('Fayl bor');
}
});
fs.constants.F_OK — faylning mavjudligini tekshiradi. R_OK — o'qish mumkinmi, W_OK — yozish mumkinmi.
Tez-tez uchraydigan xatolar
ENOENT — fayl topilmadi:
Error: ENOENT: no such file or directory, open 'config.json'
Sababi: yo'l noto'g'ri, yoki fayl hali yaratilmagan. Ko'pincha nisbiy yo'l ishlatilganda chiqadi — __dirname bilan to'liq yo'l bering.
EACCES — ruxsat yo'q:
Error: EACCES: permission denied, open '/etc/passwd'
Sababi: faylni o'qish yoki yozish uchun ruxsat yo'q. Tizim fayllariga oddiy foydalanuvchi sifatida yozib bo'lmaydi.
EEXIST — allaqachon mavjud:
Error: EEXIST: file already exists, mkdir 'uploads'
Sababi: papka yaratmoqchisiz, lekin u bor. { recursive: true } qo'shing.
EISDIR — papkaga fayl operatsiyasi:
Error: EISDIR: illegal operation on a directory, read
Sababi: readFile bilan papkani o'qishga urinish. Papka uchun readdir ishlatiladi.
Amaliy misol — oddiy fayl logger
Tushuntirilgan narsalarni birlashtirib, real ishlatilishi mumkin bo'lgan logger yozamiz:
const fs = require('fs');
const path = require('path');
const os = require('os');
const LOG_DIR = path.join(__dirname, 'logs');
const LOG_FILE = path.join(LOG_DIR, 'app.log');
// Logs papkasini yaratish (mavjud bo'lsa xato chiqarmaydi)
fs.mkdir(LOG_DIR, { recursive: true }, () => {});
function log(level, message) {
const line = `[${new Date().toISOString()}] [${level}] ${os.hostname()} — ${message}\n`;
fs.appendFile(LOG_FILE, line, 'utf8', (err) => {
if (err) console.error('Log yozishda xato:', err.message);
});
}
log('INFO', 'Server ishga tushdi');
log('INFO', 'Foydalanuvchi kirdi: ali@example.com');
log('ERROR', "Ma'lumotlar bazasiga ulanib bo'lmadi");
logs/app.log fayli:
[2026-05-07T09:00:00.000Z] [INFO] my-server — Server ishga tushdi
[2026-05-07T09:00:01.123Z] [INFO] my-server — Foydalanuvchi kirdi: ali@example.com
[2026-05-07T09:00:02.456Z] [ERROR] my-server — Ma'lumotlar bazasiga ulanib bo'lmadi
Xulosa
fs — Node.js da fayl tizimi bilan ishlash uchun asosiy modul. Callback uslubi asinxron ishlaydi — fayl o'qilayotganda server boshqa so'rovlarga javob bera oladi.
| Funksiya | Nima qiladi |
|---|---|
readFile |
Fayl o'qiydi |
writeFile |
Fayl yozadi (eski kontent o'chadi) |
appendFile |
Faylga qo'shib yozadi |
mkdir |
Papka yaratadi |
readdir |
Papka ichini o'qiydi |
stat |
Fayl haqida ma'lumot |
unlink |
Fayl o'chiradi |
rm |
Papkani ichidagi narsalar bilan o'chiradi |
rename |
Nom o'zgartiradi / ko'chiradi |
access |
Fayl mavjudligini tekshiradi |
Callback uslubi — asosni tushunish uchun yaxshi. Amalda esa fs/promises + async/await ishlatiladi — keyingi darsda.
Keyingi dars
13-dars: fs/promises — async/await bilan fayl tizimi