如何在android中安全地将文件保存到磁盘?

bri*_*rif 7 java embedded android

我写了一个Android应用程序,可以将(可能)大文件保存到SD卡.有时我在写操作期间会收到IOException,导致文件处于损坏状态.根据这个问题的答案:

问题:如何安全地写入文件?

我应该使用的策略是创建一个临时文件,然后在写完成后复制该文件.我的问题是:

1)这是Android上最安全的方法吗?(例如,你可以复制android sd卡上的文件,如果是,那么操作是原子的吗?)

2)在资源有限(磁盘空间)的嵌入式系统中,是否有人知道另一种安全写入磁盘的策略?(而不是创建两个大文件)

谢谢

thk*_*ala 10

在大多数合理平台(Linux/Android 就是其中之一)上安全创建文件的典型方法是创建一个临时文件,然后重命名该文件,如您链接到的问题和答案中所述.注意重写重命名 ; 重命名文件通常同一文件系统中的原子操作,复制文件系统不是.此外,此方法仅需要足够的空间来存储单个数据副本.

因此,您使用临时名称在目标目录中创建文件,然后使用File.renameTo()它为其指定正确的名称.通过对临时文件使用标准命名约定,您始终可以找到并删除它们,即使您的应用程序由于例如设备电源关闭而意外终止也是如此.

如果你真的是偏执狂,你可能想要插入几个电话FileDescriptor.sync()或等同...

编辑:

顺便说一下,你没有提到IOException你得到了什么样的,以及你是否已经找到了原因.如果是因为空间不足,那很好,但是如果我们谈论的是一张有问题的SD卡,那么在这种情况下就没有"安全"这样的东西了.

编辑2:

为了检查可用空间,您可以File为目标目录(即文件最终结束的目录)创建一个对象并进行调用File.getFreeSpace().请记住,此检查不提供任何保证 - 如果另一个进程将数据写入介质,您可能仍然没有足够的空间.


Paw*_*wan 7

我知道现在回答已经太晚了,但是会帮助遇到这个问题的人发现它会有所帮助.

您需要使用AtomicFile.

以下代码段可能会有所帮助.

public void writeFile(File file, byte[] data) {
    AtomicFile aFile = new AtomicFile(file);
    FileOutputStream fos = null;

    try {
        fos = aFile.startWrite();
        fos.write(data);
        // Close stream and commit new data.
        aFile.finishWrite(fos);
        fos = null;
    } catch (IOException e) {
        Log.e(TAG, "Cannot write file " + file.getPath(), e);
    } finally {
        if (fos != null) {
            // Something went wrong.
            // Close stream and roll back data.
            aFile.failWrite(fos);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个答案不晚,因为在问问题时它无法出现。AtomicFile 是在 API 级别 17 和支持库版本 22.1.0 中添加的。 (2认同)