Android(Java)中的ext4/fsync情况不清楚 [英] ext4/fsync situation unclear in Android (Java)

查看:69
本文介绍了Android(Java)中的ext4/fsync情况不清楚的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Tim Bray的文章安全保存数据" 给我留下了开放的问题.今天,它已经有一个多月的历史了,我还没有看到任何后续消息,所以我决定在这里解决这个话题.

Tim Bray's article "Saving Data Safely" left me with open questions. Today, it's over a month old and I haven't seen any follow-up on it, so I decided to address the topic here.

本文的重点是,在使用FileOutputStream时,应调用FileDescriptor.sync()以便安全.起初,我很生气,因为在我使用Java的12年中,从未见过任何Java代码进行同步.特别是因为处理文件是一件很基本的事情.另外,FileOutputStream的标准JavaDoc从未暗示过要进行同步(Java 1.0-6).经过研究,我认为ext4实际上可能是第一个需要同步的主流文件系统.(是否建议使用其他文件系统进行显式同步?)

One point of the article is that FileDescriptor.sync() should be called to be on the safe side when using FileOutputStream. At first, I was very irritated, because I never have seen any Java code doing a sync during the 12 years I do Java. Especially since coping with files is a pretty basic thing. Also, the standard JavaDoc of FileOutputStream never hinted at syncing (Java 1.0 - 6). After some research, I figured ext4 may actually be the first mainstream file system requiring syncing. (Are there other file systems where explicit syncing is advised?)

我对此事有一些一般性的想法,但我还有一些具体的问题:

I appreciate some general thoughts on the matter, but I also have some specific questions:

  1. Android何时将同步到文件系统?这可以是周期性的,也可以基于生命周期事件(例如,应用程序的流程进入后台).
  2. FileDescriptor.sync()是否负责同步元数据?那就是同步更改文件的目录.与FileChannel.force()比较.
  3. 通常,不会直接写入FileOutputStream.这是我的解决方案(您同意吗?):
  1. When will Android do the sync to the file system? This could be periodic and additionally based on life cycle events (e.g. an app's process goes to the background).
  2. Does FileDescriptor.sync() take care of syncing the meta data? That is syncing the directory of the changed file. Compare to FileChannel.force().
  3. Usually, one does not directly write into the FileOutputStream. Here's my solution (do you agree?):

FileOutputStream fileOut = ctx.openFileOutput(file, Context.MODE_PRIVATE);
BufferedOutputStream out = new BufferedOutputStream(fileOut);
try {
    out.write(something);
    out.flush();
    fileOut.getFD().sync();
} finally {
    out.close();
}

推荐答案

Android将在需要时进行同步-例如,当屏幕关闭,关闭设备等时.如果您只是在看正常"操作,则无需应用程序进行显式同步.

Android will do the sync when it needs to -- such as when the screen turns off, shutting down the device, etc. If you are just looking at "normal" operation, explicit sync by applications is never needed.

问题出在用户从设备中取出电池(或对内核进行硬重置),并且您要确保自己不会丢失任何数据.

The problem comes when the user pulls the battery out of their device (or does a hard reset of the kernel), and you want to ensure you don't lose any data.

所以首先要意识到:问题是突然断电,因此无法进行彻底关机,以及在那一刻持久存储中将要发生什么的问题.

So the first thing to realize: the issue is when power is suddenly lost, so a clean shutdown can not happen, and the question of what is going to happen in persistent storage at that point.

如果您只编写一个独立的新文件,那么您执行的操作并不重要.用户可能在写作过程中,刚开始写作之前就已经拉出电池等.如果您不同步,则意味着从完成写起到拉出电池还有一段较长的时间将会丢失数据.

If you are just writing a single independent new file, it doesn't really matter what you do. The user could have pulled the battery while you were in the middle of writing, right before you started writing, etc. If you don't sync, it just means there is some longer time from when you are done writing during which pulling the battery will lose the data.

这里最需要注意的是何时要更新文件.在这种情况下,当您下次读取文件时,想要拥有 上一个内容, 内容.您不想半途而废,也不会丢失数据.

The big concern here is when you want to update a file. In that case, when you next read the file you want to have either the previous contents, or the new contents. You don't want to get something half-way written, or lose the data.

通常是通过将数据写入新文件,然后从旧文件切换到新文件来完成的.在ext4之前,您知道,一旦完成文件写入,对其他文件的进一步操作将不会在磁盘上进行,直到该文件上的其他操作为止,因此您可以安全地删除先前的文件,或者进行依赖于新文件的操作.完全写完了.

This is often done by writing the data in a new file, and then switching to that from the old file. Prior to ext4 you knew that, once you had finished writing a file, further operations on other files would not go on disk until the ones on that file, so you could safely delete the previous file or otherwise do operations that depend on your new file being fully written.

但是现在,如果您写入新文件,然后删除旧文件,并取出电池,则在下次启动时,您可能会看到旧文件已被删除并创建了新文件,但新文件的内容并未被删除.完全的.通过执行同步,您可以确保新文件已在此时完全写入,因此可以根据该状态进行进一步的更改(例如删除旧文件).

However now if you write the new file, then delete the old one, and the battery is pulled, when you next boot you may see that the old file is deleted and new file created but the contents of the new file is not complete. By doing the sync, you ensure that the new file is completely written at that point so can do further changes (such as deleting the old file) that depend on that state.

这篇关于Android(Java)中的ext4/fsync情况不清楚的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆