العمل مع نظام الملفات في TypeScript: دليل عملي

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

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

ابدأ الدورة

مقدمة: لماذا نحتاج العمل مع نظام الملفات في TypeScript؟

\n\n

كل تطبيق عاجلاً أم آجلاً يحتاج إلى التفاعل مع نظام الملفات: حفظ الإعدادات، معالجة الملفات المرفوعة، تسجيل السجلات أو إدارة المشاريع. TypeScript، كونه طبقة فوق JavaScript، يوفر للمطور أدوات قوية للعمل مع الملفات والدلائل من خلال وحدة fs (File System) من Node.js.

\n\n

في هذه المقالة، سنشرح من خلال أمثلة عملية العمليات الأساسية مع نظام الملفات في TypeScript: قراءة وكتابة الملفات، إنشاء وحذف الدلائل، بالإضافة إلى معالجة الأخطاء. سيتم تقديم جميع الأمثلة باستخدام التصنيف الصارم (strict typing)، وهي الميزة الرئيسية لـ TypeScript.

\n\n

الوحدات الأساسية للعمل مع نظام الملفات

\n\n

قبل الانتقال إلى التطبيق العملي، دعنا نتعرف على ثلاث وحدات أساسية ستكون ضرورية للعمل:

\n\n
    \n
  • fs — الوحدة الأساسية لعمليات نظام الملفات (قراءة، كتابة، حذف)
  • \n
  • fs/promises — نسخة من وحدة fs مع دعم الـ Promises (موصى بها للكود الحديث)
  • \n
  • path — أداة مساعدة للعمل مع مسارات الملفات والدلائل
  • \n
\n\n

لاستيراد الوحدات في TypeScript، استخدم الصيغة التالية:

\n\n
import * as fs from 'fs';\nimport * as fsPromises from 'fs/promises';\nimport * as path from 'path';
\n\n

ملاحظة: للعمل بشكل صحيح مع TypeScript، تأكد من تعيين الخيارات "moduleResolution": "node" و "esModuleInterop": true في ملف tsconfig.json الخاص بك.

\n\n

قراءة الملفات: الطرق المتزامنة وغير المتزامنة

\n\n

القراءة المتزامنة مع التصنيف

\n\n

الطرق المتزامنة تمنع تنفيذ الكود حتى اكتمال العملية. استخدمها فقط للملفات الصغيرة أو أثناء التحميل الأولي للتطبيق:

\n\n
import * as fs from 'fs';\nimport * as path from 'path';\n\nfunction readConfigSync(): Record<string, unknown> {\n  const configPath = path.join(__dirname, 'config.json');\n  \n  try {\n    const data = fs.readFileSync(configPath, 'utf-8');\n    return JSON.parse(data) as Record<string, unknown>;\n  } catch (error) {\n    if (error instanceof Error) {\n      console.error('خطأ في قراءة الإعدادات:', error.message);\n    }\n    return {};\n  }\n}\n\nconst config = readConfigSync();\nconsole.log('تم تحميل الإعدادات:', config);
\n\n

القراءة غير المتزامنة مع async/await (الطريقة الموصى بها)

\n\n

للكود الإنتاجي، استخدم دائمًا الطرق غير المتزامنة. TypeScript يعمل بشكل ممتاز مع async/await:

\n\n
import { readFile } from 'fs/promises';\nimport * as path from 'path';\n\ninterface UserData {\n  id: number;\n  name: string;\n  email: string;\n}\n\nasync function readUserData(fileName: string): Promise<UserData[]> {\n  const filePath = path.resolve('data', fileName);\n  \n  try {\n    const rawData = await readFile(filePath, { encoding: 'utf-8' });\n    const users: UserData[] = JSON.parse(rawData);\n    return users;\n  } catch (error) {\n    if (error instanceof Error) {\n      throw new Error(`تعذر قراءة الملف ${fileName}: ${error.message}`);\n    }\n    throw error;\n  }\n}\n\n// الاستخدام\n(async () => {\n  try {\n    const users = await readUserData('users.json');\n    console.log(`تم تحميل ${users.length} مستخدم`);\n  } catch (error) {\n    console.error(error);\n  }\n})();
\n\n

كتابة وتحديث الملفات

\n\n

إنشاء واستبدال الملفات

\n\n

لكتابة البيانات إلى ملف، استخدم طريقة writeFile. ستقوم بإنشاء الملف إذا لم يكن موجودًا، أو استبداله إذا كان موجودًا:

\n\n
import { writeFile, mkdir } from 'fs/promises';\nimport * as path from 'path';\n\ninterface LogEntry {\n  timestamp: string;\n  level: 'info' | 'warn' | 'error';\n  message: string;\n}\n\n                

المدونات

توصيات الكتب