إتقان نظام الملفات: التعامل مع الملفات في JavaScript

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا التعامل مع الملفات في JavaScript أمر لا غنى عنه

\n\n

تخيل أنك قائد سفينة فضائية. مهمتك هي إدارة مخازن الشحن وخزانات الأكسجين وسجل الرحلة. في عالم تطوير الويب، نظام الملفات هو تلك المخازن، وJavaScript هي لوحة التحكم الخاصة بك. بدون مهارة التعامل مع الملفات، ستبقى عالقًا في المدار: لن تتمكن من حفظ إعدادات المستخدم، أو تحميل إعدادات الخادم، أو معالجة ملفات السجلات.

\n\n

يعتقد الكثير من المبتدئين أن JavaScript تعيش فقط في المتصفح ولا تستطيع لمس الملفات على القرص الصلب. هذه خرافة! مع ظهور Node.js (وحتى في المتصفحات الحديثة عبر File API)، أصبحت JavaScript أداة كاملة للتعامل مع نظام الملفات. اليوم سنتعلم كيفية قراءة وكتابة وحذف ونقل الملفات، وكيفية تجنب فخاخ البرمجة غير المتزامنة.

\n\n

بالمناسبة، إذا كنت في بداية رحلتك مع البرمجة، أنصحك أولاً بدراسة أساسيات JavaScript — سيساعدك ذلك على فهم الأمثلة أدناه بشكل أسرع.

\n\n

أين يعمل JavaScript مع الملفات؟ عالمين — نهجان مختلفان

\n\n

قبل الغوص في الكود، دعنا نوضح: عمليات الملفات في JS تنقسم إلى معسكرين.

\n\n

1. JavaScript من جهة الخادم (Node.js)

\n

هنا لدينا وصول كامل إلى نظام الملفات: إنشاء، حذف، إعادة تسمية، قراءة التدفقات — كل ما تشتهيه النفس. نعمل من خلال الوحدة المدمجة fs (File System). إنها مثل سكين سويسري للتعامل مع الملفات.

\n\n

2. JavaScript من جهة العميل (المتصفح)

\n

المتصفح هو "صندوق رمل" به قيود. لا يمكنك ببساطة قراءة أي ملف من جهاز المستخدم (وإلا لكان المخترقون يحتفلون). ولكن يمكنك العمل مع الملفات التي يختارها المستخدم بنفسه عبر <input type="file">، أو عبر واجهات FileReader و Blob.

\n\n

في هذه المقالة، سنركز على Node.js، لكن في النهاية سنقدم مكافأة — مثال للمتصفح.

\n\n

وحدة fs: أداتك الرئيسية

\n\n

في Node.js، يبدأ التعامل مع الملفات باستيراد الوحدة fs:

\n\n
const fs = require('fs'); // الطريقة القديمة\n// أو\nimport fs from 'fs'; // إذا كنت تستخدم وحدات ES
\n\n

لـ fs ثلاثة أوضاع عمل: متزامن، غير متزامن مع دوال الاسترجاع، وغير متزامن مع Promises. سنستخدم الأخير مع async/await، لأنه نهج حديث وسهل القراءة.

\n\n

قراءة ملف: من البسيط إلى المعقد

\n\n

لنفترض أن لدينا ملف data.txt يحتوي على نص. أسهل طريقة لقراءته:

\n\n
import { readFile } from 'fs/promises';\n\nasync function readMyFile() {\n  try {\n    const data = await readFile('data.txt', 'utf-8');\n    console.log(data);\n  } catch (err) {\n    console.error('خطأ في القراءة:', err.message);\n  }\n}\n\nreadMyFile();
\n\n

ما المهم هنا؟ 'utf-8' هو ترميز النص. إذا لم تحدده، ستحصل على Buffer خام يجب تحويله إلى نص. للملفات النصية، حدد الترميز دائمًا.

\n\n

إذا كان الملف كبيرًا (مثل ملف سجل بحجم 500 ميجابايت)، فإن قراءته بالكامل فكرة سيئة. هنا تأتي التدفقات (streams) للإنقاذ:

\n\n
import { createReadStream } from 'fs';\nimport { createInterface } from 'readline';\n\nasync function readLargeFile() {\n  const stream = createReadStream('bigfile.log', 'utf-8');\n  const rl = createInterface({ input: stream });\n\n  for await (const line of rl) {\n    console.log('سطر:', line);\n    // معالجة كل سطر أثناء القراءة\n  }\n}\n\nreadLargeFile();
\n\n

الكتابة في ملف: إنشاء وإضافة

\n\n

الكتابة نوعان: استبدال (write) وإضافة (append). الفرق واضح: write سيمسح الملف القديم، append سيضيف في النهاية.

\n\n
import { writeFile, appendFile } from 'fs/promises';\n\n//                

المدونات

توصيات الكتب