Saving data safely
我们知道,在Android平台中,保存数据有3种方式:local file, preference和sqlite。在任何系统中,无论是fat、ntfs、ext还是YAFFS等等文件系统,保存数据的操作总不能保证绝对的安全。单以android系统来说,在2.3之前的版本,几乎都是使用YAFFS文件系统的,因为YAFFS系统的buffer等设计,会导致一些即便是调用了write()方法,甚至于调用了close()方法之后,数据都没有被写道flash存储中去。所以从android2.3开始,文件系统将开始迁移到ext4。但是即便使用了ext4之后,还是会存在一些buffering的问题。2.3版本发布之后,会有一些列I/O相关的例子展示该怎么做。
如果你使用preferences和sqlite存储数据,就不用担心buffer的问题。当你需要在flash上存储文件的时候,就要考虑这个问题了。
原文:
The reason this should be of concern to Android developers is that with 2.3, an increasing proportion of devices, notably including the Nexus S, are going to be moving from YAFFS to the ext4 filesystem, which buffers much more aggressively; thus you need to be more assertive about making sure your data gets to permanent storage when you want it to.
If you just use SharedPreferences or SQLite, you can relax, because we’ve made sure they Do The Right Thing about buffering. But if you have your own on-disk format, keep in mind that your data doesn't actually consistently reach the flash chip when you write() it or even when you close() it. There are several layers of buffering between you and the hardware! And because of ext4 buffering policy, any POSIX guarantees that you thought you had before (but actually didn't), you especially don't have now.
Some Android devices are already running non-YAFFS filesystems, but as we brought up the Nexus S, buffering issues have actually bitten us a couple of times in framework code. When the Gingerbread source code becomes available, you’ll find lots of examples of how file I/O should be done.
To start with, for raw data consider using one of the synchronous modes of java.io.RandomAccessFile, which take care of calling fsync() for you in the appropriate way. If you can’t, you’ll want Java code that looks something like this.
public static boolean sync(FileOutputStream stream) { try { if (stream != null) { stream.getFD().sync(); } return true; } catch (IOException e) { } return false;
In some applications, you might even want to check the return status of the close() call.
Now of course, there are two sides to this story. When you call fsync() and force the data onto storage, that can be slow; worse, unpredictably slow. So be sure to call it when you need it, but be careful not to call it carelessly.
Background reading if you want to know more:
ext4 and data loss by Jonathan Corbet.
ext4 vs fsync, my take by Alexander Larsson.
Don’t fear the fsync! by Ted Ts’o.
页:
[1]