我编写了一个Android应用程序,可以将(可能)大文件保存到SD卡。有时我在写操作期间会收到IOException,导致文件处于损坏状态。根据这个问题的答案:
Question: How to safely write to a file?
我应该使用的策略是创建一个临时文件,然后在写完成后复制该文件。我的问题是:
1)这是Android上最安全的方法吗? (例如,你可以复制android sd卡上的文件,如果是,那么原子操作是什么?)
2)在资源有限(磁盘空间)的嵌入式系统中,是否有人知道另一种安全写入磁盘的策略? (而不是创建两个大文件)
由于
答案 0 :(得分:10)
在大多数合理平台上安全创建文件的典型方法(Linux / Android 其中之一)是创建一个临时文件,然后重命名该文件,正如问题中提到的那样你链接的答案。注意强调重命名;重命名文件通常在同一文件系统中的原子操作,复制一个不是。此外,此方法仅需要足够的空间来存储单个数据副本。
因此,您使用临时名称在目标目录中创建文件,然后使用File.renameTo()
为其指定正确的名称。通过对临时文件使用标准命名约定,您始终可以找到并删除它们,即使您的应用程序由于例如设备断电。
如果你真的很偏执,你可能想要拨打FileDescriptor.sync()
或同等数量的电话......
编辑:
顺便说一句,你没有提到你正在获得什么样的IOException
以及你是否已经找到了原因。如果是因为空间不足,那很好,但是如果我们谈论的是一张有问题的SD卡,那么在这种情况下就没有“安全”这样的东西了。
编辑2:
为了检查可用空间,您可以为目标目录(即文件最终到达的目录)创建一个File
对象,然后调用File.getFreeSpace()
。请注意,此检查不提供任何保证 - 例如,您可能仍然没有足够的空间另一个进程将数据写入介质。
答案 1 :(得分:6)
我知道现在为时已晚,无法回答,但会帮助遇到此问题的任何人都会觉得有帮助。
您需要使用AtomicFile。
以下代码段可能会有所帮助。
private void writeFile(File file, byte[] data) {
file.mkdirs();
try {
AtomicFile aFile = new AtomicFile(file);
FileOutputStream fos = aFile.startWrite();
fos.write(data);
aFile.finishWrite(fos);
} catch (IOException ioe) {
Log.e(TAG, "Cannot write file " + file.getPath());
}
}
答案 2 :(得分:0)
我不知道是否要复制它,但重命名临时文件是典型的。如果在写入期间遇到异常,只需删除临时文件。