Η εσωτερική μνήμη εφαρμογής είναι ένας αποκλειστικός χώρος στη συσκευή, προσβάσιμος μόνο στη συγκεκριμένη εφαρμογή μέσω απομονωμένης αποθήκευσης. Σύμφωνα με το Android Developers, 2026, κάθε εφαρμογή λαμβάνει τον δικό της sandbox κατάλογο, στον οποίο άλλες εφαρμογές δεν έχουν άμεση πρόσβαση. Αυτή η προσέγγιση προστατεύει τα δεδομένα από μη εξουσιοδοτημένη ανάγνωση και εξασφαλίζει σταθερή λειτουργία σε περιβάλλον πολλαπλών εργασιών κινητών συσκευών.
Βασικά σημεία
Context.getFilesDir(), getCacheDir() και getDataDir() για πρόσβαση στην εσωτερική μνήμηNSDocumentDirectory και NSCachesDirectory στο Sandbox κοντέινερ της εφαρμογήςΗ εσωτερική μνήμη εφαρμογής είναι ένας απομονωμένος κατάλογος που το λειτουργικό σύστημα εκχωρεί σε κάθε εφαρμογή κατά την εγκατάστασή της. Σε αυτόν τον κατάλογο δεν έχουν πρόσβαση άλλες εφαρμογές ούτε ο χρήστης μέσω τυπικών διαχειριστών αρχείων. Το σύστημα εγγυάται ότι τα δεδομένα εντός αυτού του καταλόγου θα διαγραφούν πλήρως κατά την απεγκατάσταση της εφαρμογής. Αυτή η προσέγγιση αποτελεί τη βάση του μοντέλου ασφαλείας των κινητών λειτουργικών συστημάτων, αποτρέποντας τη διαρροή εμπιστευτικών πληροφοριών μεταξύ προγραμμάτων.
Σε αντίθεση με τον εξωτερικό αποθηκευτικό χώρο (κάρτα SD), η εσωτερική μνήμη είναι πάντα διαθέσιμη και δεν απαιτεί έλεγχο ύπαρξης μέσου. Η ταχύτητα ανάγνωσης και εγγραφής στη μνήμη NAND flash των σύγχρονων συσκευών φτάνει τα 800–900 MB/s για σειριακή ανάγνωση και 200–300 MB/s για σειριακή εγγραφή, που είναι συγκρίσιμη με SATA SSD. Το μέγεθος της εκχωρούμενης περιοχής εξαρτάται από τη συνολική χωρητικότητα της συσκευής και την πολιτική του κατασκευαστή: σε συσκευές με 64 GB flash μνήμη, η εφαρμογή λαμβάνει 16–64 MB αρχικού χώρου με δυνατότητα επέκτασης ανάλογα με τις ανάγκες.
Η αρχιτεκτονική της εσωτερικής αποθήκευσης διαφέρει σε Android και iOS. Στο Android κάθε εφαρμογή λαμβάνει έναν κατάλογο /data/data/<package_name>/, μέσα στον οποίο το σύστημα δημιουργεί υποκαταλόγους files/, cache/ και databases/. Στο iOS η εφαρμογή λειτουργεί σε ένα Sandbox κοντέινερ με καταλόγους Documents/, Library/ και tmp/, καθένας από τους οποίους έχει τον δικό του σκοπό και πολιτική δημιουργίας αντιγράφων ασφαλείας.
Οι προγραμματιστές έχουν στη διάθεσή τους διάφορες μεθόδους αποθήκευσης δεδομένων στην εσωτερική μνήμη της εφαρμογής. Κάθε μέθοδος επιλύει ένα συγκεκριμένο πρόβλημα και είναι κατάλληλη για συγκεκριμένο τύπο δεδομένων. Η επιλογή της σωστής μεθόδου επηρεάζει άμεσα την απόδοση της εφαρμογής, την ευκολία ανάπτυξης και την ασφάλεια των δεδομένων χρήστη.
Η πιο χαμηλού επιπέδου μέθοδος είναι η άμεση εγγραφή αρχείων στον κατάλογο files. Η εφαρμογή μπορεί να δημιουργήσει οποιαδήποτε αρχεία και καταλόγους εντός του sandbox της. Αυτή η μέθοδος είναι κατάλληλη για αποθήκευση αρχείων πολυμέσων, εγγράφων χρήστη και οποιωνδήποτε δυαδικών δεδομένων που δεν απαιτούν δομημένη οργάνωση. Στο Android η πρόσβαση στον κατάλογο γίνεται μέσω της κλήσης Context.getFilesDir(), η οποία επιστρέφει την απόλυτη διαδρομή προς τον κατάλογο αρχείων της εφαρμογής. Στο iOS ανάλογη λειτουργία εκτελεί η NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).
Για αποθήκευση ζευγών κλειδιού-τιμής το Android προσφέρει SharedPreferences και το πιο σύγχρονο DataStore βασισμένο σε Kotlin coroutines και πρωτόκολλο protobuf. Το SharedPreferences αποθηκεύει δεδομένα σε αρχείο XML εντός του καταλόγου /data/data/<package>/shared_prefs/. Παρά την ευκολία χρήσης, το SharedPreferences έχει μειονεκτήματα: η σύγχρονη εγγραφή μπορεί να προκαλέσει καθυστερήσεις στο νήμα UI, ενώ η έλλειψη ασφάλειας τύπων αυξάνει τον κίνδυνο σφαλμάτων. Το DataStore λύνει αυτά τα προβλήματα παρέχοντας ασύγχρονο API βασισμένο σε Flow και πλήρη υποστήριξη τύπων μέσω σχημάτων protobuf.
Για δομημένα δεδομένα με σχεσιακές σχέσεις η βέλτιστη επιλογή είναι η SQLite ή το περιτύλιγμα Room. Η βάση δεδομένων αποθηκεύεται σε ένα μοναδικό αρχείο εντός του καταλόγου databases/ και υποστηρίζει πλήρη σύνταξη SQL. Το Room είναι η επίσημη βιβλιοθήκη Jetpack που παρέχει ασφαλή ως προς τύπους API, αυτόματη μετεγκατάσταση σχήματος και υποστήριξη coroutines. Το μέγεθος της βάσης δεδομένων μπορεί να φτάσει αρκετά gigabyte χωρίς σημαντική απώλεια απόδοσης με σωστή ευρετηρίαση. Η SQLite σε κινητές συσκευές διαχειρίζεται έως και 50.000 λειτουργίες εγγραφής ανά δευτερόλεπτο σε ένα σύγχρονο κορυφαίο επεξεργαστή.
Για αποθήκευση εμπιστευτικών δεδομένων, όπως διακριτικά ταυτοποίησης και κλειδιά κρυπτογράφησης, το Android παρέχει το EncryptedSharedPreferences. Αυτό το περιτύλιγμα πάνω από τα τυπικά SharedPreferences κρυπτογραφεί αυτόματα κλειδιά και τιμές χρησιμοποιώντας AES256-GCM-None. Η κρυπτογράφηση εκτελείται σε επίπεδο αρχείου πριν από την εγγραφή στο δίσκο, επομένως ακόμα και με φυσική πρόσβαση στη συσκευή, ένας εισβολέας δεν μπορεί να διαβάσει το περιεχόμενο. Το EncryptedSharedPreferences αποτελεί μέρος της βιβλιοθήκης AndroidX Security, η οποία περιλαμβάνει επίσης το EncryptedFile για κρυπτογράφηση ολόκληρων αρχείων.
Το Android SDK παρέχει ένα σύνολο μεθόδων για εργασία με την εσωτερική μνήμη μέσω της κλάσης Context. Κάθε μέθοδος επιστρέφει τη διαδρομή προς έναν συγκεκριμένο κατάλογο συστήματος εντός του sandbox της εφαρμογής. Ας εξετάσουμε τις βασικές λειτουργίες εγγραφής και ανάγνωσης αρχείων με παράδειγμα σε Kotlin.
Η κύρια μέθοδος για λήψη της διαδρομής προς τον εσωτερικό κατάλογο αρχείων είναι η context.filesDir. Επιστρέφει ένα αντικείμενο File που δείχνει στον κατάλογο /data/data/<package>/files/. Κατά την πρώτη κλήση, το σύστημα δημιουργεί αυτόματα όλους τους απαραίτητους γονικούς καταλόγους. Το μέγεθος των αρχείων στην εσωτερική μνήμη δεν είναι ρητά περιορισμένο, αλλά ο συνολικός όγκος δεδομένων δεν πρέπει να υπερβαίνει τον διαθέσιμο χώρο του διαμερίσματος /data, το οποίο συνήθως αποτελεί το 60–80% της συνολικής χωρητικότητας flash της συσκευής.
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 ή εξάντληση inode του συστήματος αρχείων.
val imagesDir = File(context.filesDir, "images")
if (imagesDir.mkdirs()) {
println("Ο κατάλογος δημιουργήθηκε")
}
val imageFile = File(imagesDir, "photo.jpg")
imageFile.writeBytes(byteArray)
Για έλεγχο του διαθέσιμου χώρου πριν από την εγγραφή μεγάλων αρχείων χρησιμοποιήστε File.getFreeSpace() ή File.getUsableSpace(). Η δεύτερη μέθοδος επιστρέφει τον αριθμό bytes που είναι διαθέσιμος στην τρέχουσα εφαρμογή λαμβάνοντας υπόψη τις ποσοστώσεις ασφαλείας — είναι πιο ακριβής σε περιβάλλον πολλών χρηστών. Εάν ο διαθέσιμος χώρος είναι μικρότερος από το αναμενόμενο μέγεθος αρχείου, εμφανίστε ένα μήνυμα στον χρήστη και προτείνετε να ελευθερώσει χώρο στις ρυθμίσεις της συσκευής.
Στο iOS κάθε εφαρμογή λειτουργεί σε ένα απομονωμένο Sandbox κοντέινερ. Το σύστημα δεν παρέχει API για έξοδο από τα όριά του χωρίς ειδικά δικαιώματα. Το κύριο εργαλείο για εργασία με το σύστημα αρχείων είναι η κλάση FileManager από το Foundation framework. Το 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 | Cache Directory | External Storage |
|---|---|---|---|
| Ορατότητα σε άλλες εφαρμογές | Κρυφή | Κρυφή | Προσβάσιμη |
| Διαγραφή κατά την απεγκατάσταση | Πλήρης | Πλήρης | Εξαρτάται από τη θέση |
| Αντίγραφα ασφαλείας | Στο Android — όχι, στο iOS — ναι (Documents) | Όχι | Μόνο κατά συγχρονισμό |
| Διαθεσιμότητα χωρίς μέσο | Πάντα | Πάντα | Απαιτεί κάρτα SD |
| Κίνδυνος απώλειας δεδομένων | Ελάχιστος | Υψηλός | Μέτριος |
| Συνιστώμενο μέγεθος αρχείων | Έως 100 MB | Έως 50 MB | Οποιοδήποτε |
Εσωτερική μνήμη είναι βέλτιστη για αποθήκευση διαμορφώσεων εφαρμογής, αρχείων βάσης δεδομένων και εγγράφων χρήστη που δεν πρέπει να είναι προσβάσιμα σε άλλα προγράμματα. Ο κατάλογος προσωρινής μνήμης προορίζεται για προσωρινά αρχεία που μπορούν να αναδημιουργηθούν στην επόμενη χρήση: ληφθείσες εικόνες, απαντήσεις API, ενδιάμεσα δεδομένα επεξεργασίας. Η εξωτερική αποθήκευση είναι η καταλληλότερη για μεγάλα αρχεία πολυμέσων (φωτογραφίες, βίντεο, μουσική) και δεδομένα που ο χρήστης θέλει να μοιράζεται με άλλες εφαρμογές μέσω κοινής πρόσβασης.
Η επιλογή τύπου αποθήκευσης επηρεάζει επίσης την αξιολόγηση της εφαρμογής στο Google Play και το App Store. Οι εφαρμογές που αποθηκεύουν μεγάλους όγκους δεδομένων στην εσωτερική μνήμη χωρίς καθαρισμό λαμβάνουν αρνητικές κριτικές: οι χρήστες παραπονιούνται για έλλειψη χώρου. Σύμφωνα με έρευνα της App Annie, το 62% των χρηστών διαγράφει μια εφαρμογή εάν καταλαμβάνει πάνω από 500 MB εσωτερικής μνήμης της συσκευής χωρίς δυνατότητα καθαρισμού.
Η σωστή διαχείριση της εσωτερικής μνήμης της εφαρμογής βελτιώνει την απόδοση, την ασφάλεια και την εμπειρία χρήστη. Οι ακόλουθες συστάσεις βασίζονται στην επίσημη τεκμηρίωση Android και iOS, καθώς και στην πρακτική εμπειρία ανάπτυξης εφαρμογών με εκατομμύρια εγκαταστάσεις.
Ιδιαίτερη προσοχή πρέπει να δοθεί στη δοκιμή ακραίων περιπτώσεων. Ελέγξτε τη συμπεριφορά της εφαρμογής κατά την υπερχείλιση της εσωτερικής μνήμης, κατά την απότομη διακοπή εγγραφής (κατάρρευση εφαρμογής, κλήση) και κατά την επαναφορά από αντίγραφο ασφαλείας iOS. Σε κάθε ένα από αυτά τα σενάρια, τα δεδομένα πρέπει να παραμένουν συνεπή ή να επαναφέρονται στην τελευταία σταθερή κατάσταση. Χρησιμοποιήστε συναλλακτικά αρχεία: γράψτε δεδομένα σε ένα προσωρινό αρχείο και στη συνέχεια μετονομάστε το ατομικά στο αρχείο προορισμού. Αυτό αποτρέπει την ανάγνωση κατεστραμμένων δεδομένων σε περίπτωση αποτυχίας εγγραφής.
Μην ξεχνάτε τον έλεγχο από τον χρήστη. Παρέχετε στις ρυθμίσεις της εφαρμογής επιλογή καθαρισμού προσωρινών δεδομένων και εμφάνιση του χρησιμοποιούμενου όγκου εσωτερικής μνήμης. Σύμφωνα με το Google Play Console, οι εφαρμογές με αυτή τη λειτουργία λαμβάνουν 18% περισσότερες θετικές κριτικές στην κατηγορία "Απόδοση".
Συχνές ερωτήσεις
Όλα τα δεδομένα από την εσωτερική μνήμη της εφαρμογής διαγράφονται πλήρως. Το λειτουργικό σύστημα εγγυάται την απουσία υπολειπόμενων αρχείων, συμπεριλαμβανομένων βάσεων δεδομένων, ρυθμίσεων και προσωρινών αρχείων. Τα δεδομένα στην εξωτερική αποθήκευση ενδέχεται να διατηρηθούν.
Χωρίς πρόσβαση root στη συσκευή, άλλες εφαρμογές δεν μπορούν να διαβάσουν αρχεία από το Internal Storage άλλης εφαρμογής. Στο Android απαιτούνται δικαιώματα υπερχρήστη, ενώ στο iOS η απομόνωση εξασφαλίζεται σε επίπεδο πυρήνα μέσω Sandbox.
Δεν υπάρχει ρητό όριο, αλλά ο συνολικός όγκος περιορίζεται από τον ελεύθερο χώρο στο διαμέρισμα /data. Συνιστάται να μην υπερβαίνετε τα 100 MB ανά εφαρμογή — μεγαλύτεροι όγκοι είναι προτιμότερο να τοποθετούνται σε εξωτερική αποθήκευση ή στο cloud.
filesDir προορίζεται για μόνιμα δεδομένα εφαρμογής και δεν διαγράφεται από το σύστημα χωρίς λόγο. cacheDir είναι για προσωρινά αρχεία που το σύστημα μπορεί να διαγράψει σε περίπτωση έλλειψης μνήμης. Το σύστημα δεν εγγυάται τη διατήρηση του cacheDir.
Η άμεση αντιγραφή από το Internal Storage σε κάρτα SD απαγορεύεται από την πολιτική ασφαλείας. Χρησιμοποιήστε το MediaStore API σε Android 10+ ή το SAF (Storage Access Framework) για δημιουργία αντιγράφων δεδομένων σε κοινόχρηστο χώρο με τη συγκατάθεση του χρήστη.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης