这些方法如何在磁盘上丢失/导致数据丢失?

我有一个程序,每隔一段时间(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." ); } }