fs — readFile, writeFile, mkdir, unlink

~20 daq · Node.js · Core Modullar

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

⚠️ writeFile faylning eski kontentini to'liq o'chiradi va yangisini yozadi. Eski ma'lumot yo'qoladi. Agar qo'shib yozish kerak bo'lsa — appendFile ishlatiladi.

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

⚠️ rename faqat bir xil disk ichida ishlaydi. Boshqa diskka ko'chirishda EXDEV xatosi chiqadi. Bunday holda copyFile + unlink ishlatiladi.


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