5-bo‘lim

Fayllar bilan ishlash

fs/promises bilan o'qish va yozish, papkalar, JSON saqlash, xatolarni ushlash va existsSync nima uchun yomon.

🕑 12 daqiqa o‘qish 📄 659 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Uchta shakl
  2. Yozish va o'qish
  3. writeFile ustiga yozadi
  4. Papkalar
  5. Fayl haqida ma'lumot
  6. JSON saqlash
  7. Xatolarni ushlash
  8. existsSync nima uchun yomon
  9. Nusxalash va nom o'zgartirish
  10. Katta fayllar haqida
  11. Xulosa

Fayl tizimi bilan ishlash - Node ning brauzerdan eng katta farqi. Buning uchun node:fs moduli bor.

Uchta shakl #

fs moduli uch xil ko'rinishda keladi:

ImportUslub
node:fs/promisesawait - tavsiya etiladi
node:fsQayta chaqiruv (callback)
node:fs (...Sync)Bloklaydigan

Bu darslikda birinchisi ishlatiladi.

Yozish va o'qish #

JavaScript
import { writeFile, readFile, appendFile, rm } from "node:fs/promises";

await writeFile("qaydlar.txt", "Birinchi qator\n", "utf8");
await appendFile("qaydlar.txt", "Ikkinchi qator\n", "utf8");

const mazmun = await readFile("qaydlar.txt", "utf8");
console.log(mazmun.trimEnd());
console.log("Qatorlar:", mazmun.trimEnd().split("\n").length);

await rm("qaydlar.txt");
Natija
Birinchi qator
Ikkinchi qator
Qatorlar: 2
FunksiyaNima qiladi
writeFileYozadi (ustiga yozadi)
appendFileOxiriga qo'shadi
readFileO'qiydi
rmO'chiradi
"utf8" ni unutmang

readFile ni kodlashsiz chaqirsangiz, u satr emas, Buffer qaytaradi:

JavaScript
const xom = await readFile("fayl.txt");
console.log(typeof xom);        // object

Buffer - xom baytlar. Rasm yoki arxiv uchun aynan shu kerak, matn uchun esa "utf8" bering.

Buni unutish odatiy xato: keyin mazmun.split(...) ishlamay qoladi va sabab darhol ravshan bo'lmaydi.

writeFile ustiga yozadi #

JavaScript
import { writeFile, readFile, rm } from "node:fs/promises";

await writeFile("sinov.txt", "birinchi mazmun", "utf8");
await writeFile("sinov.txt", "ikkinchi", "utf8");

console.log(await readFile("sinov.txt", "utf8"));

await writeFile("sinov.txt", " qo'shildi", { flag: "a" });
console.log(await readFile("sinov.txt", "utf8"));

await rm("sinov.txt");
Natija
ikkinchi
ikkinchi qo'shildi

writeFile so'ramasdan eski mazmunni yo'q qiladi. { flag: "a" } bersangiz, u appendFile kabi ishlaydi.

Papkalar #

JavaScript
import { mkdir, writeFile, readdir, rm } from "node:fs/promises";

await mkdir("sinov/ichki", { recursive: true });

await writeFile("sinov/b.txt", "B", "utf8");
await writeFile("sinov/a.txt", "A", "utf8");
await writeFile("sinov/ichki/c.txt", "C", "utf8");

const fayllar = await readdir("sinov");
console.log(fayllar.sort());

const hammasi = await readdir("sinov", { recursive: true });
console.log(hammasi.sort().length);

await rm("sinov", { recursive: true, force: true });
Natija
[ 'a.txt', 'b.txt', 'ichki' ]
4

{ recursive: true } mkdir da ota-papkalarni ham yaratadi, rm da esa butun daraxtni o'chiradi.

readdir tartibni kafolatlamaydi

Yuqorida .sort() bejiz yozilmagan.

readdir fayllarni operatsion tizim bergan tartibda qaytaradi. Linux da bu ko'pincha alifbo tartibi emas, balki fayl tizimining ichki tartibi. Boshqa kompyuterda natija boshqacha bo'lishi mumkin.

Tartib muhim bo'lsa - masalan, hisobot yoki migratsiyalar ro'yxati - har doim o'zingiz saralang.

Bu darslikdagi hamma misol shu qoidaga amal qiladi.

Fayl haqida ma'lumot #

JavaScript
import { writeFile, stat, rm } from "node:fs/promises";

await writeFile("olcham.txt", "12345", "utf8");

const holat = await stat("olcham.txt");

console.log("Hajmi:", holat.size);
console.log("Faylmi:", holat.isFile());
console.log("Papkami:", holat.isDirectory());
console.log("Vaqt bormi:", holat.mtime instanceof Date);

await rm("olcham.txt");
Natija
Hajmi: 5
Faylmi: true
Papkami: false
Vaqt bormi: true

mtime ning o'zi chop etilmadi - u har safar boshqacha bo'lardi.

JSON saqlash #

JavaScript
import { writeFile, readFile, rm } from "node:fs/promises";

const talabalar = [
    { ism: "Malika", ball: 88 },
    { ism: "Husanboy", ball: 92 },
];

await writeFile("talabalar.json", JSON.stringify(talabalar, null, 2));

const xom = await readFile("talabalar.json", "utf8");
const qayta = JSON.parse(xom);

console.log(qayta.length);
console.log(qayta[1].ism, qayta[1].ball);
console.log(xom.split("\n").length > 1);

await rm("talabalar.json");
Natija
2
Husanboy 92
true

JSON.stringify(qiymat, null, 2) - uchinchi argument chekinish beradi va faylni odam o'qiy oladigan qiladi.

Xatolarni ushlash #

JavaScript
import { readFile } from "node:fs/promises";

try {
    await readFile("yoq-bunday-fayl.txt", "utf8");
} catch (xato) {
    console.log("Kod:", xato.code);
    console.log("Topilmadimi:", xato.code === "ENOENT");
    console.log("Xato turi:", xato instanceof Error);
}
Natija
Kod: ENOENT
Topilmadimi: true
Xato turi: true

Node ning fayl xatolarida code maydoni bo'ladi. Eng ko'p uchraydiganlari:

KodMa'nosi
ENOENTFayl yoki papka yo'q
EACCESRuxsat yetmaydi
EEXISTAllaqachon mavjud
EISDIRFayl kutilgan edi, papka keldi
ENOTEMPTYPapka bo'sh emas
Xatoni matn bo'yicha emas, code bo'yicha tekshiring

Xato xabari tilga va Node versiyasiga qarab o'zgarishi mumkin. code esa barqaror - u operatsion tizimdan keladi.

JavaScript
if (xato.code === "ENOENT") {
    // fayl yo'q - bu normal bo'lishi mumkin
} else {
    throw xato;   // boshqa xato - yuqoriga uzating
}

Eng muhimi: hamma xatoni bir xil qabul qilmang. "Fayl yo'q" - ko'pincha kutilgan hol, "ruxsat yo'q" esa jiddiy muammo.

existsSync nima uchun yomon #

JavaScript
import { writeFile, readFile, rm } from "node:fs/promises";

async function xavfsizOqi(yol) {
    try {
        return await readFile(yol, "utf8");
    } catch (xato) {
        if (xato.code === "ENOENT") return null;
        throw xato;
    }
}

await writeFile("bor.txt", "mazmun", "utf8");

console.log(await xavfsizOqi("bor.txt"));
console.log(await xavfsizOqi("yoq.txt"));

await rm("bor.txt");
Natija
mazmun
null
Avval tekshirib, keyin o'qish - poyga holati

Ko'p qo'llanmalarda shunday yoziladi:

JavaScript
if (existsSync(yol)) {
    const mazmun = await readFile(yol, "utf8");
}

Muammo: tekshiruv bilan o'qish orasida vaqt o'tadi. O'sha oniqda boshqa jarayon faylni o'chirib yuborishi mumkin - va readFile baribir yiqiladi.

Bu TOCTOU (tekshiruvdan foydalanishgacha) deb ataladi.

To'g'ri yondashuv - yuqoridagi kabi: shunchaki urinib ko'ring va ENOENT ni ushlang. Bu tezroq ham, ishonchliroq ham.

Nusxalash va nom o'zgartirish #

JavaScript
import { writeFile, copyFile, rename, readdir, rm } from "node:fs/promises";
import { mkdir } from "node:fs/promises";

await mkdir("ish", { recursive: true });
await writeFile("ish/asl.txt", "mazmun", "utf8");

await copyFile("ish/asl.txt", "ish/nusxa.txt");
await rename("ish/nusxa.txt", "ish/yangi-nom.txt");

console.log((await readdir("ish")).sort());

await rm("ish", { recursive: true, force: true });
Natija
[ 'asl.txt', 'yangi-nom.txt' ]

rename faylni ko'chirish uchun ham ishlatiladi - yangi yo'l boshqa papkada bo'lsa, fayl o'sha yerga o'tadi.

Katta fayllar haqida #

readFile butun faylni xotiraga yuklaydi

10 KB uchun bu muammo emas. 2 GB uchun esa dastur xotirasi tugaydi va jarayon o'ladi.

Katta fayllar uchun oqimlar (streams) ishlatiladi: fayl bo'laklab o'qiladi va xotirada faqat bitta bo'lak turadi.

Buni 9-bo'limda batafsil ko'ramiz.

Oddiy qoida: fayl hajmini oldindan bilmasangiz yoki u foydalanuvchidan kelsa - oqim ishlating.

Amaliy topshiriq
  1. Faylga yozib, uni qayta o'qing.
  2. "utf8" ni tushirib qoldirib, natija turini ko'ring.
  3. appendFile bilan qator qo'shing.
  4. writeFile eski mazmunni yo'q qilishini isbotlang.
  5. { recursive: true } bilan ichma-ich papka yarating.
  6. readdir natijasini saralab chiqaring.
  7. stat bilan fayl hajmini oling.
  8. Obyektni JSON qilib saqlab, qayta o'qing.
  9. Mavjud bo'lmagan faylni o'qib, xato.code ni chiqaring.
  10. ENOENT ni ushlab, null qaytaradigan funksiya yozing.

Xulosa #

  • node:fs/promises - zamonaviy, await bilan ishlaydigan shakl.
  • Matn uchun "utf8" bering, aks holda Buffer keladi.
  • writeFile ustiga yozadi; qo'shish uchun appendFile yoki { flag: "a" }.
  • { recursive: true } papka daraxtini yaratadi va o'chiradi.
  • readdir tartibni kafolatlamaydi - har doim o'zingiz saralang.
  • Fayl xatolarini xato.code bo'yicha ajrating, matn bo'yicha emas.
  • existsSync + o'qish - poyga holati; shunchaki urinib ko'ring va ENOENT ni ushlang.
  • Katta fayllar uchun readFile emas, oqim kerak.

Keyingi bo'limda yo'llar va process bilan ishlaymiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.