我已经写了一个android应用程序,可以将(潜在的)大文件保存到SD卡。在写操作期间,我偶尔会得到一个IOException,这会导致文件处于损坏状态。根据这个问题的答案:
Question: How to safely write to a file?
我应该使用的策略是创建一个临时文件,然后在写入完成后复制该文件。我的问题是:
1)这是Android上最安全的方法吗?(例如,你可以复制android SD卡上的文件吗?如果可以,操作是原子的吗?)
2)在资源(磁盘空间)有限的嵌入式系统中,有没有人知道另一种安全写入磁盘的策略?(而不是创建两个大文件)
谢谢
发布于 2011-10-30 06:51:53
在大多数合理的平台(Linux/Android是其中之一)上安全创建文件的典型方法是创建一个临时文件,然后重命名该文件,如您链接的问题和答案中所提到的那样。注意对重命名的强调;重命名文件通常是同一文件系统中的原子操作,而复制文件则不是。此外,此方法只需要足够的空间来存储数据的单个副本。
因此,您可以使用临时名称在目标目录中创建一个文件,然后使用File.renameTo()为其指定一个合适的名称。通过使用临时文件的标准命名约定,您始终可以找到并删除它们,即使您的应用程序由于设备关机等原因而意外终止。
如果你真的是偏执狂,你可能想要插入一些对FileDescriptor.sync()或类似的调用...
编辑:
顺便说一句,你没有提到你得到的是什么类型的IOException,以及你是否已经找到了它的原因。如果是由于空间不足,好吧,但如果我们讨论的是有问题的SD卡,那么在这种情况下就没有“安全”这回事了。
编辑2:
为了检查可用的空闲空间,您可以为目标目录(即您的文件将结束的目录)创建一个File对象并调用File.getFreeSpace()。请记住,此检查不能提供任何保证-如果另一个进程将数据写入介质,您仍可能最终没有足够的空间。
发布于 2017-02-23 03:16:49
我知道这已经来不及回答了,但我会帮助任何遇到这个问题的人,他们会发现它很有用。
您需要使用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);
}
}
}发布于 2011-10-30 06:55:23
我不知道我是否会复制它,但重命名临时文件是典型的做法。如果在写入过程中遇到异常,只需删除临时文件即可。
https://stackoverflow.com/questions/7940582
复制相似问题