التخزين الداخلي للتطبيق هو مساحة مخصصة على الجهاز يمكن الوصول إليها فقط من خلال تطبيق معين عبر تخزين معزول. وفقًا لـ Android Developers, 2026، يحصل كل تطبيق على دليل sandbox خاص به لا يمكن للتطبيقات الأخرى الوصول المباشر إليه. يحمي هذا النهج البيانات من القراءة غير المصرح بها ويضمن عملًا مستقرًا في بيئة تعدد المهام للأجهزة المحمولة.
الوجبات الرئيسية
Context.getFilesDir() و getCacheDir() و getDataDir() للوصول إلى التخزين الداخليNSDocumentDirectory و NSCachesDirectory في حاوية Sandbox للتطبيقالتخزين الداخلي للتطبيق هو دليل معزول يخصصه نظام التشغيل لكل تطبيق أثناء تثبيته. لا يمكن للتطبيقات الأخرى أو المستخدم الوصول إلى هذا الدليل عبر مديري الملفات القياسيين. يضمن النظام حذف جميع البيانات داخل هذا الدليل بالكامل عند إلغاء تثبيت التطبيق. يشكل هذا النهج أساس نموذج أمان أنظمة التشغيل المحمولة، مما يمنع تسرب المعلومات السرية بين البرامج.
على عكس التخزين الخارجي (بطاقة SD)، فإن التخزين الداخلي متاح دائمًا ولا يتطلب التحقق من وجود الوسائط. تصل سرعات القراءة والكتابة في ذاكرة NAND Flash للأجهزة الحديثة إلى 800–900 ميجابايت/ثانية للقراءة المتسلسلة و200–300 ميجابايت/ثانية للكتابة المتسلسلة، وهو ما يمكن مقارنته بـ SATA SSD. يعتمد حجم المساحة المخصصة على السعة الإجمالية للجهاز وسياسة الشركة المصنعة: على الأجهزة ذات سعة 64 جيجابايت من ذاكرة الفلاش، يحصل التطبيق على 16 إلى 64 ميجابايت من المساحة الأولية مع إمكانية التوسع حسب الحاجة.
تختلف بنية التخزين الداخلي بين Android و iOS. على Android، يتلقى كل تطبيق دليل /data/data/<package_name>/، حيث يقوم النظام بإنشاء أدلة فرعية files/ و cache/ و databases/. على iOS، يعمل التطبيق في حاوية Sandbox مع أدلة Documents/ و Library/ و tmp/، لكل منها غرضه وسياسة النسخ الاحتياطي الخاصة به.
يتوفر للمطورين عدة طرق لحفظ البيانات في التخزين الداخلي للتطبيق. تحل كل طريقة مهمة محددة وتناسب نوعًا معينًا من البيانات. يؤثر اختيار الطريقة الصحيحة بشكل مباشر على أداء التطبيق وسهولة التطوير وأمان بيانات المستخدم.
الطريقة الأكثر انخفاضًا هي الكتابة المباشرة للملفات في دليل الملفات. يمكن للتطبيق إنشاء أي ملفات وأدلة داخل صندوق الحماية الخاص به. هذه الطريقة مناسبة لتخزين ملفات الوسائط ووثائق المستخدم وأي بيانات ثنائية لا تتطلب تنظيمًا منظمًا. على Android، يتم الوصول إلى الدليل عبر استدعاء Context.getFilesDir()، الذي يعيد المسار المطلق إلى دليل ملفات التطبيق. على iOS، تؤدي وظيفة NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) غرضًا مشابهًا.
لتخزين أزواج المفتاح-القيمة، يقدم Android SharedPreferences و DataStore الأحدث المبني على coroutines الخاصة بـ Kotlin وبروتوكول protobuf. يخزن SharedPreferences البيانات في ملف XML داخل الدليل /data/data/<package>/shared_prefs/. على الرغم من سهولة الاستخدام، فإن SharedPreferences له عيوب: الكتابة المتزامنة قد تسبب تأخيرات في سلسلة واجهة المستخدم، وغياب أمان الأنواع يزيد من خطر الأخطاء. يحل DataStore هذه المشاكل من خلال توفير API غير متزامن يعتمد على Flow ودعم كامل للأنواع عبر مخططات protobuf.
للبيانات المهيكلة ذات العلاقات الترابطية، يكون الخيار الأمثل هو SQLite أو الغلاف Room. يتم تخزين قاعدة البيانات في ملف واحد داخل دليل databases/ وتدعم بناء جملة SQL الكامل. Room هي مكتبة Jetpack رسمية توفر API آمن للأنواع وهجرة تلقائية للمخطط ودعم coroutines. يمكن أن يصل حجم قاعدة البيانات إلى عدة جيجابايت دون فقدان كبير في الأداء مع الفهرسة المناسبة. يعالج SQLite على الأجهزة المحمولة ما يصل إلى 50,000 عملية كتابة في الثانية على معالج رئيسي حديث.
لتخزين البيانات السرية مثل رموز المصادقة ومفاتيح التشفير، يوفر Android EncryptedSharedPreferences. هذا الغلاف فوق SharedPreferences القياسي يشفر تلقائيًا المفاتيح والقيم باستخدام AES256-GCM-None. يتم التشفير على مستوى الملف قبل الكتابة على القرص، لذلك حتى مع الوصول الفعلي إلى الجهاز، لا يمكن للمهاجم قراءة المحتوى. EncryptedSharedPreferences جزء من مكتبة AndroidX Security، والتي تتضمن أيضًا EncryptedFile لتشفير الملفات بأكملها.
يوفر Android SDK مجموعة من الطرق للعمل مع التخزين الداخلي عبر فئة Context. تعيد كل طريقة مسارًا إلى دليل نظام معين داخل صندوق الحماية للتطبيق. دعونا نستعرض العمليات الأساسية لكتابة وقراءة الملفات باستخدام Kotlin كمثال.
الطريقة الرئيسية للحصول على المسار إلى دليل الملفات الداخلي هي context.filesDir. تعيد كائن File يشير إلى الدليل /data/data/<package>/files/. عند أول وصول، يقوم النظام تلقائيًا بإنشاء جميع الأدلة الأصلية اللازمة. حجم الملفات في التخزين الداخلي غير محدود بشكل صريح، لكن الحجم الإجمالي للبيانات يجب ألا يتجاوز المساحة المتاحة على القسم /data، والتي تتراوح عادة بين 60–80% من إجمالي سعة ذاكرة الفلاش.
val context = getApplicationContext()
val file = File(context.filesDir, "notes.txt")
file.writeText("محتوى الملاحظة")
val content = file.readText()
println("تمت القراءة: $content")
الطريقتان writeText و readText هما دالتان موسعتان من المكتبة القياسية لـ Kotlin. تديران تلقائيًا فتح وإغلاق التدفقات، مما يمنع تسرب الذاكرة. للبيانات الثنائية، استخدم writeBytes و readBytes، اللتان لا تتطلبان ترميزًا وتعملان مع مصفوفات ByteArray. عند العمل مع ملفات كبيرة، يُنصح باستخدام تدفقات مخزنة: BufferedReader و BufferedWriter للنصوص، BufferedInputStream و BufferedOutputStream للبيانات الثنائية.
لتنظيم الملفات في تسلسل هرمي، أنشئ أدلة فرعية داخل filesDir. يساعد هذا في هيكلة البيانات حسب النوع: الصور والوثائق وملفات التصدير. تنشئ طريقة mkdirs() جميع الأدلة المفقودة في المسار، بما في ذلك المتداخلة. تأكد من نجاح عملية الإنشاء — تعيد الطريقة true فقط عند إنشاء أدلة جديدة. عادةً ما ترتبط أخطاء الإنشاء بنقص المساحة على القسم /data أو استنفاد عُقد نظام الملفات.
val imagesDir = File(context.filesDir, "images")
if (imagesDir.mkdirs()) {
println("تم إنشاء الدليل")
}
val imageFile = File(imagesDir, "photo.jpg")
imageFile.writeBytes(byteArray)
للتحقق من المساحة المتاحة قبل كتابة ملفات كبيرة، استخدم File.getFreeSpace() أو File.getUsableSpace(). تعيد الطريقة الثانية عدد البايتات المتاحة للتطبيق الحالي مع مراعاة حصص الأمان — وهي أكثر دقة في سياق الأجهزة متعددة المستخدمين. إذا كانت المساحة المتاحة أقل من حجم الملف المتوقع، اعرض رسالة للمستخدم واقترح تحرير مساحة في إعدادات الجهاز.
على iOS، يعمل كل تطبيق في حاوية Sandbox معزولة. لا يوفر النظام API للخروج من حدودها دون أذونات خاصة. الأداة الرئيسية للعمل مع نظام الملفات هي فئة FileManager من إطار Foundation. تتضمن حاوية Sandbox عدة أدلة قياسية، لكل منها سياسة النسخ الاحتياطي الخاصة به.
دليل Documents مخصص لـ بيانات المستخدم التي يجب الاحتفاظ بها بين جلسات تشغيل التطبيق واستعادتها من النسخ الاحتياطي. يقوم iOS تلقائيًا بتضمين هذا الدليل في النسخ الاحتياطية لـ iCloud و iTunes. تعيد طريقة urls(for:in:) مصفوفة من عناوين URL للدليل المطلوب — العنصر الأول في المصفوفة هو الأساسي.
let fm = FileManager.default
let docs = fm.urls(
for: .documentDirectory,
in: .userDomainMask
).first!
let fileURL = docs.appendingPathComponent("data.plist")
try data.write(to: fileURL)
يدعم FileManager مجموعة كاملة من عمليات الملفات: الإنشاء والنسخ والنقل والحذف وإعادة التسمية. يمكن لكل عملية طرح خطأ، لذلك يجب تغليف جميع الاستدعاءات في بناء do-catch. انتبه بشكل خاص لحذف الملفات — العملية غير قابلة للعكس، واستعادة البيانات بعد removeItem(at:) مستحيلة بدون نسخة احتياطية مسبقة.
لا يجب تضمين جميع البيانات في حاوية Sandbox في النسخ الاحتياطي لـ iCloud. على سبيل المثال، الصور المخبأة التي تم تنزيلها أو ملفات المعالجة المؤقتة لا تحتاج إلى استعادة — سيتم إعادة إنشائها عند الاستخدام التالي. لاستبعاد دليل أو ملف من النسخ الاحتياطي، عيِّن السمة isExcludedFromBackup إلى true. توصي Apple دائمًا باستبعاد البيانات التي يمكن استعادتها عن بُعد من النسخ الاحتياطي، لتقليل استخدام تخزين iCloud وتقليل وقت الاستعادة.
var cacheURL = fm.urls(
for: .cachesDirectory,
in: .userDomainMask
).first!
cacheURL.hasExcludedFromBackupKey = true
var values = URLResourceValues()
values.isExcludedFromBackup = true
try cacheURL.setResourceValues(values)
لكل نوع من أنواع التخزين على الجهاز المحمول غرضه وقواعد استخدامه. يساعد فهم هذه الاختلافات المطور على اختيار المكان المناسب لكل نوع من البيانات. فيما يلي مقارنة لأنواع التخزين الثلاثة الرئيسية المتاحة للتطبيق.
| الخاصية | Internal Storage | دليل التخزين المؤقت | External Storage |
|---|---|---|---|
| الرؤية للتطبيقات الأخرى | مخفي | مخفي | متاح |
| الحذف عند إلغاء تثبيت التطبيق | كامل | كامل | يعتمد على الموقع |
| النسخ الاحتياطي | Android — لا، iOS — نعم (Documents) | لا | فقط عند المزامنة |
| التوفر بدون وسائط | دائمًا | دائمًا | يتطلب بطاقة SD |
| خطر فقدان البيانات | أدنى | مرتفع | متوسط |
| حجم الملف الموصى به | حتى 100 ميجابايت | حتى 50 ميجابايت | أي |
التخزين الداخلي مثالي لتخزين إعدادات التطبيق وملفات قاعدة البيانات ووثائق المستخدم التي لا يجب أن تكون متاحة للبرامج الأخرى. دليل التخزين المؤقت مخصص للملفات المؤقتة التي يمكن إعادة إنشائها عند الاستخدام التالي: الصور التي تم تنزيلها واستجابات API وبيانات المعالجة الوسيطة. التخزين الخارجي هو الأنسب لملفات الوسائط الكبيرة (الصور والفيديو والموسيقى) والبيانات التي يرغب المستخدم في مشاركتها مع التطبيقات الأخرى من خلال الوصول المشترك.
يؤثر اختيار نوع التخزين أيضًا على تصنيف التطبيق في Google Play و App Store. التطبيقات التي تخزن كميات كبيرة من البيانات في التخزين الداخلي دون تنظيف تتلقى مراجعات سلبية: يشتكي المستخدمون من نقص المساحة. وفقًا لدراسة App Annie، يقوم 62% من المستخدمين بحذف التطبيق إذا كان يشغل أكثر من 500 ميجابايت من التخزين الداخلي للجهاز دون خيار التنظيف.
الإدارة السليمة للتخزين الداخلي للتطبيق تحسن الأداء والأمان وتجربة المستخدم. تستند التوصيات التالية إلى الوثائق الرسمية لـ Android و iOS، بالإضافة إلى الخبرة العملية في تطوير التطبيقات بملايين التنزيلات.
يجب إيلاء اهتمام خاص لاختبار الحالات الحدية. تحقق من سلوك التطبيق عند امتلاء التخزين الداخلي، وعند انقطاع عملية الكتابة بشكل غير متوقع (تعطل التطبيق، مكالمة واردة)، وعند الاستعادة من نسخة احتياطية لـ iOS. في كل من هذه السيناريوهات، يجب أن تظل البيانات متسقة أو تستعيد إلى آخر حالة مستقرة. استخدم الملفات المعاملاتية: اكتب البيانات في ملف مؤقت، ثم أعد تسميته بشكل ذري إلى الهدف. يمنع هذا قراءة البيانات التالفة عند فشل الكتابة.
لا تنسَ التحكم للمستخدم. وفر في إعدادات التطبيق خيارًا لتنظيف البيانات المؤقتة وعرض الحجم المشغول من التخزين الداخلي. وفقًا لـ Google Play Console، تتلقى التطبيقات بهذه الميزة 18% أكثر من المراجعات الإيجابية في فئة «الأداء».
الأسئلة الشائعة
يتم حذف جميع البيانات من التخزين الداخلي للتطبيق بالكامل. يضمن نظام التشغيل عدم وجود ملفات متبقية، بما في ذلك قواعد البيانات والإعدادات والملفات المؤقتة. قد تبقى البيانات الموجودة على التخزين الخارجي.
بدون وصول جذري إلى الجهاز، لا يمكن للتطبيقات الأخرى قراءة الملفات من التخزين الداخلي لتطبيق آخر. على Android، يتطلب هذا صلاحيات المستخدم المتميز، بينما على iOS، يتم تطبيق العزل على مستوى النواة عبر Sandbox.
لا يوجد حد صريح، لكن الحجم الإجمالي مقيد بـ المساحة المتاحة على القسم /data. يُنصح بعدم تجاوز 100 ميجابايت لكل تطبيق — الأحجام الأكبر من الأفضل وضعها في التخزين الخارجي أو في السحابة.
filesDir مخصص للبيانات الدائمة للتطبيق ولا يحذفه النظام إلا عند الضرورة. cacheDir للملفات المؤقتة التي قد يحذفها النظام عند نقص الذاكرة. لا يضمن النظام استمرارية cacheDir.
النسخ المباشر من التخزين الداخلي إلى بطاقة SD محظور بواسطة سياسة الأمان. استخدم MediaStore API على Android 10+ أو SAF (Storage Access Framework) لإنشاء نسخ من البيانات في التخزين المشترك بموافقة المستخدم.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا