As Android developers, we have a few options for persisting our application data across runs:
- SQLite database
- external storage on the SD card, or through networking
- SharedPreferences (see previous article)
- or we can use the phone’s internal file system, and store data in files which are, by default, only visible to our application.
Why would we want to use internal files to persist data? Because of the following considerations:
- If a SQLite database would be overkill for our use case, and we, as always, are looking for the simplest solution that works
- If SharedPreferences doesn’t meet our functional requirements. For example, we might need to persist entire objects, not just primitives. or our application is using multiple processes (not supported by the SharedPreferences API at this time)
- If external storage on the SD card does not meet our security requirements, since all other applications can read the files stored on the SD card. Besides the user could remove those files accidentally.
- If external Storage on some Web server is not an option, because we want our application to be able to access the persisted data even in the absence of internet connection.
Using an internal file to persist data is pretty simple: we save and retrieve data using the Android.content.Context ‘s openFileOutput() and openFileInput(), which return a java.io.FileOutputStream and a java.io.FileInputStream respectively. From there, it’s just our typical Java file I/O operations.
String FILENAME = "xfile"; // saving into file FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE); // write I/O using write() and close() //... // retrieving from file FileInputStream fis = context.openFileInput(FILENAME); // read I/O using read() and close()
Context.MODE_PRIVATE means our internal files are only visible to us. There are other modes, like MODE_APPEND, MODE_WORLD_READABLE and MODE_WORLD_WRITABLE which are self-explanatory. We want to use MODE_APPEND when we need to add data to the end of the file, otherwise we will overwrite the file every time we write to it.
But where exactly is that internal file saved? If we really want to know, its absolute path is returned by the Context’s getFilesDir() call. Another method of Context, fileList(), will return an array of all the files saved by our application.
These internal files are of course deleted once our application itself is removed by the user. But just in case we would like to delete an internal file ourselves in the course of our application workflow, there’s always the Context’s deleteFile() method for that purpose.