Issue
I have written an android app that saves (potentially) large files to the SD Card. Occasionally I get an IOException during the write operation which causes the file to be left in a corrupt state. Based on the answer to this question:
href="https://stackoverflow.com/questions/1812115/how-to-safely-write-to-a-file">Question: How to safely write to a file?
the strategy I should use is to create a temporary file and then copy this file once the write has completed. My questions are:
1) Is this the safest approach on Android? (e.g. Can you copy files on the android sd card and if so is the operation atomic?)
2) In an embedded system with limited resources (disk space) does anyone know of another strategy for safely writing to a disk? (instead of creating two large files)
Thanks
Solution
The typical way to safely create a file on most reasonable platforms (Linux/Android is one of them) is to create a temporary file and then rename the file, as mentioned in the question & answers that you linked to. Note the emphasis on rename; renaming a file is usually an atomic operation within the same filesystem, copying one is not. In addition, this method only requires enough space for a single copy of the data.
Therefore you create a file in the target directory using a temporary name and then use File.renameTo()
to give it a proper name. By using a standard naming convention for the temporary files you can always find and delete them, even if your application terminates unexpectedly due to e.g. a device power-off.
If you are really paranoid, you may want to insert a few calls to FileDescriptor.sync()
or equivalent...
EDIT:
BTW, you do not mention what kind of IOException
your are getting and whether you have tracked down its cause. If it's due to insufficient space, fine, but if we are talking about a faulty SD card, then there is no such thing as "safe" in this case.
EDIT 2:
In order to check the available free space, you can create a File
object for the destination directory (i.e. the directory where your file will end up) and call File.getFreeSpace()
. Keep in mind that this check does not provide any guarantees - you may still end up without enough space if e.g. another process writes data to the medium.
Answered By - thkala
Answer Checked By - Marilyn (JavaFixing Volunteer)