这些方法如何在磁盘上丢失/导致数据丢失?
我有一个程序,每隔一段时间(15秒左右)将其设置和数据写入磁盘。
如果程序正在运行并且计算机突然关闭 – 例如,在墙上切断电源 – 不知何故,磁盘上的所有数据文件都将更改为空文件。
这是我的代码,我认为我的目的是为了防止这种失败,但基于测试失败仍然存在:
SaveAllData – 经常调用,也调用JavaFX.Application.stop()。
public void saveAllData () { createNecessaryFolders(); saveAlbumsAndTracks(); saveSources(); saveCurrentList(); saveQueue(); saveHistory(); saveLibraryPlaylists(); saveSettings(); saveHotkeys(); }
CreateNecessaryFolders
private void createNecessaryFolders () { if ( !playlistsDirectory.exists() ) { boolean playlistDir = playlistsDirectory.mkdirs(); } }
保存function – 它们看起来都像这样
public void saveCurrentList () { File tempCurrentFile = new File ( currentFile.toString() + ".temp" ); try ( ObjectOutputStream currentListOut = new ObjectOutputStream( new FileOutputStream( tempCurrentFile ) ) ) { currentListOut.writeObject( player.getCurrentList().getState() ); currentListOut.flush(); currentListOut.close(); Files.move( tempCurrentFile.toPath(), currentFile.toPath(), StandardCopyOption.REPLACE_EXISTING ); } catch ( Exception e ) { LOGGER.warning( e.getClass().getCanonicalName() + ": Unable to save current list to disk, continuing." ); } }
Github存储库提交存在此问题的位置。 请参见Persister.java。
正如我所说,当电源突然切断时, 通过此方法保存的所有设置文件都会被消隐。 这对我来说特别没意义,因为它们是按顺序调用的,我确保在调用move()之前将文件写入磁盘并刷新。
知道如何发生这种情况吗? 我想通过调用flush,close,然后移动,我会确保在覆盖旧数据之前将数据写入磁盘。 不知何故,情况并非如此,但我一无所知。 有什么建议么?
注意:这些文件仅由这些函数写入,并且只能通过相应的load()函数读取。 在我的程序中的任何其他位置都没有其他文件访问权限。
注2:我在Ubuntu Linux 16.10上遇到过这种情况。 我还没有在其他平台上测试它。
将StandardCopyOption.ATOMIC_MOVE
添加到Files.move()
调用可以解决问题:
public void saveCurrentList () { File tempCurrentFile = new File ( currentFile.toString() + ".temp" ); try ( ObjectOutputStream currentListOut = new ObjectOutputStream( new FileOutputStream( tempCurrentFile ) ) ) { currentListOut.writeObject( player.getCurrentList().getState() ); currentListOut.flush(); currentListOut.close(); Files.move( tempCurrentFile.toPath(), currentFile.toPath(), StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE ); } catch ( Exception e ) { LOGGER.warning( e.getClass().getCanonicalName() + ": Unable to save current list to disk, continuing." ); } }