Kodokon kodokon.com

نظام الملفات: القراءة والكتابة باستخدام fs/promises

تقرأ الملفات وتكتبها باستخدام الوحدة fs/promises، وتبني مسارات موثوقة بفضل الوحدة path.

8 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

في المتصفح، لا يُسمح لـ JavaScript بلمس الملفات الموجودة على قرصك: وهي مسألة أمان. أما Node، من ناحية أخرى، فتعمل مباشرة على جهازك ويمكنها قراءة الملفات وكتابتها بفضل الوحدة fs (نظام الملفات، file system). سنستخدم نسختها الحديثة، fs/promises، التي تُرجِع كل دالة فيها وعدًا (promise) - أنت تعرف بالفعل كيف تنتظره باستخدام await، الذي رأيته في مسار JavaScript. لاحظ البادئة node: في الاستيرادات: فهي توضّح أن الوحدة تأتي من Node نفسها، لا من node_modules. وخبر سار: في وحدة ES، يعمل await مباشرة على مستوى الملف، دون دالة محيطة.

JAVASCRIPT
import { writeFile } from "node:fs/promises";

await writeFile("notes.txt", "First note\n");
console.log("File created!");
تنشئ writeFile ملف notes.txt إذا لم يكن موجودًا، بالنص المُعطى كوسيط ثانٍ.

للقراءة، المنطق نفسه مع readFile. وسيطها الثاني ضروري: utf8 يحدّد الترميز (encoding)، أي طريقة ترجمة البايتات المخزّنة على القرص إلى نص مقروء. فإذا أغفلته، تُرجِع Node كائن Buffer - بايتات خام - بدلًا من سلسلة نصية.

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

const text = await readFile("notes.txt", "utf8");
console.log(text);
يصل محتوى الملف على شكل سلسلة نصية، جاهزة للمعالجة.

لنتحدث عن المسارات. يبدأ المسار النسبي (notes.txt، data/log.txt) من المجلد الحالي؛ أما المسار المطلق (C:\... أو /home/...) فيبدأ من جذر القرص. فخّ كلاسيكي: يفصل Windows بين المجلدات بـ \، بينما يفصل بينها macOS وLinux بـ /. تحلّ الوحدة path المشكلة: تجمّع path.join الأجزاء بالفاصل الصحيح، مهما كان النظام. لنجمعها مع mkdir، التي تنشئ مجلدًا.

JAVASCRIPT
import path from "node:path";
import { mkdir, writeFile } from "node:fs/promises";

const file = path.join("data", "log.txt");

await mkdir("data", { recursive: true });
await writeFile(file, "First log\n");
console.log("Written to:", file);
يتجنّب الخيار recursive حدوث خطأ إذا كان مجلد data موجودًا بالفعل.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. ماذا تُرجِع readFile إذا أغفلت الوسيط الثاني utf8؟
    • سلسلة نصية فارغة
    • خطأ: الترميز إلزامي
    • كائن Buffer، أي بايتات الملف الخام
  2. ماذا تفعل writeFile إذا كان الملف الهدف موجودًا بالفعل؟
    • تستبدل المحتوى الموجود بالكامل بالنص الجديد
    • تضيف النص الجديد في نهاية الملف
    • ترفض الكتابة وتُطلق خطأً
    • تنشئ نسخة احتياطية تلقائيًا
  3. ما فائدة path.join لبناء مسار؟
    • تنشئ المجلدات المفقودة في المسار
    • تجمّع الأجزاء بالفاصل الصحيح المناسب للنظام
    • تتحقق من وجود الملف قبل المتابعة