我有一个程序,每隔一段时间(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();
}
}
保存功能 - 它们看起来都像这样
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 repository to commit where this problem exists. See Persister.java.
正如我所说,当电源突然切断时此方法保存的所有设置文件都会被消隐。这对我来说特别没意义,因为它们是按顺序调用的,我确保在调用move()之前将文件写入磁盘并刷新。
知道如何发生这种情况吗?我想通过调用flush,close,然后移动,我会确保在覆盖旧数据之前将数据写入磁盘。不知何故,事实并非如此,但我一无所知。有什么建议?
注意:这些文件仅 写入这些文件,仅从相应的load()函数读取。在我的程序中的任何其他位置都没有其他文件访问权限。
注意2:我在Ubuntu Linux 16.10上遇到过这种情况。我还没有在其他平台上测试它。
答案 0 :(得分:0)
将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." );
}
}