如果在写入时发生错误,如何防止文件擦除?

How to prevent file wipe if an error occurs while writing to it?

这是我在很多应用中遇到的问题。 我想更改文件中的信息,该文件的版本已过时。 在这种情况下,我在将歌曲添加到播放列表后更新记录播放列表的文件。 (作为参考,我正在为 android 创建一个应用程序。)

问题是如果我 运行 这个代码:

FileOutputStream output = new FileOutputStream(file);
output.write(data.getBytes());
output.close();

并且如果在尝试写入文件时发生 IOException,则数据将丢失(因为创建 FileOutputStream 的实例会清空文件)。有没有更好的方法来做到这一点,所以如果发生 IOException,旧数据保持不变?还是只在文件为只读时才会出现此错误,所以我只需要检查一下?

我唯一的"work around"是通知用户错误,并给用户正确的数据,用户必须手动更新。虽然这可能适用于开发人员,但如果发生这种情况,可能会出现很多问题。此外,在这种情况下,用户自己没有编辑文件的权限,因此 "work around" 根本不起作用。

抱歉,如果有人问过这个问题。搜索时找不到结果。

提前致谢!

确保不擦除文件的一种方法是先创建一个具有不同名称的新文件。如果写入该文件成功,您可以删除旧文件并重命名新文件。

重命名有可能失败。为了完全安全,您的文件可以根据创建时间命名。例如,如果您的文件名为 save.dat,您可以将文件保存的时间(从 System.currentTimeMillis() 开始)添加到文件名的末尾。然后,无论以后发生什么(包括删除旧文件失败或重命名新文件失败),您都可以恢复最近的成功保存。我在下面包含了一个示例实现,它将时间表示为附加到文件扩展名的 16 位零填充十六进制数。名为 save.dat 的文件将被保存为 save.dat00000171ed431353 或类似的名称。

// name includes the file extension (i.e. "save.dat").
static File fileToSave(File directory, String name) {
    return new File(directory, name + String.format("%016x", System.currentTimeMillis()));
}

// return the entire array if you need older versions for which deletion failed. This could be useful for attempting to purge any unnecessary older versions for instance.
static File fileToLoad(File directory, String name) {
    File[] files = directory.listFiles((dir, n) -> n.startsWith(name));
    Arrays.sort(files, Comparator.comparingLong((File file) -> Long.parseLong(file.getName().substring(name.length()), 16)).reversed());
    return files[0];
}