在Java中存储状态
广泛的讨论问题。 是否有任何库允许我在Java中存储我的应用程序的执行状态?
例如,我有一个处理文件的应用程序,现在应用程序可能会被迫在某个时刻突然关闭。我想存储有关所有文件已处理的内容以及所有文件尚未处理的信息,以及处理的处理阶段正在进行的流程。
是否已有任何抽象此function的库或我必须从头开始实现它?
您正在寻找的是可以使用Java Serialization API执行的序列化 。
如果您决定使用已知的库(如Apache Commons Lang)及其SerializationUtils类(它本身构建在Java Serialization API之上),则可以编写更少的代码。
使用最新的,将应用程序状态序列化/反序列化为文件只需几行即可完成。
你要做的唯一事情是创建一个包含你的应用程序状态的类,让我们调用它… ApplicationState
:-)它看起来像这样:
class ApplicationState { enum ProcessState { READ_DONE, PROCESSING_STARTED, PROCESSING_ENDED, ANOTHER_STATE; } private List filesDone, filesToDo; private String currentlyProcessingFile; private ProcessState currentProcessState; }
使用这样的结构,并使用SerializationUtils,序列化通过以下方式完成:
try { ApplicationState state = new ApplicationState(); ... // File to serialize object to String fileName = "applicationState.ser"; // New file output stream for the file FileOutputStream fos = new FileOutputStream(fileName); // Serialize String SerializationUtils.serialize(state, fos); fos.close(); // Open FileInputStream to the file FileInputStream fis = new FileInputStream(fileName); // Deserialize and cast into String String ser = (String) SerializationUtils.deserialize(fis); System.out.println(ser); fis.close(); } catch (Exception e) { e.printStackTrace(); }
听起来Java Preferences API对您来说可能是一个不错的选择。 这可以轻松存储用户/系统设置,您可以随时更新/检索。 http://docs.oracle.com/javase/1.4.2/docs/guide/lang/preferences.html
从头开始制作非常简单。 你可以这样说:
-
有一个DB(或只是一个文件)存储处理进度的信息。 就像是:
Id|fileName|status|metadata
-
一旦开始处理文件,就立即输入该表。 Ans标记状态为
PROCESSING
,您可以存储中间状态,最后在完成后可以将状态设置为DONE
。这样,在重启时,您就会知道处理的文件是什么; 当进程关闭/崩溃时,什么是in-citu文件。 (显然)从哪里开始。
在应用程序松散耦合的大型企业环境中(并且无法保证应用程序是否可用或可能崩溃),我们使用Message Queue执行相同的操作以确保可靠的体系结构。
有太多的方法可以提及。 我会选择你认为最简单的选项。
您可以使用;
- 记录完成内容的文件(以及要做的事情)
- JMS上的持久队列(支持多个进程,甚至在不同的机器上)
- 嵌入式或远程数据库。
我狂热的一种方法是使用内存映射文件。 一个很好的function是,如果应用程序死亡或被杀死(如果操作系统没有崩溃)信息不会丢失,这意味着您不必刷新它,也不用担心丢失数据。
这是有效的,因为数据部分由操作系统管理,这意味着它使用很少的堆(即使是TB数据),操作系统处理加载和刷新到磁盘使其更快(并使大小比实际主存大) 。
BTW:当操作系统将数据刷新到磁盘时,这种方法甚至可以使用kill -9
。 为了测试这个,我使用Unsafe.getByte(0)
,它在更改后立即使用SEG故障崩溃应用程序(如下一个机器代码指令),它仍然将更改写入磁盘。
如果你拉动电源,这将无法工作,但你必须非常快。 您可以使用内存映射文件在继续之前强制数据到磁盘,但我不知道如何测试它确实有效。 ;)
我有一个库,可以使内存映射文件更容易使用
https://github.com/peter-lawrey/Java-Chronicle
它的读取时间不长,你可以用它作为例子。
Apache Commons Configuration API: http : //commons.apache.org/proper/commons-configuration/userguide/howto_filebased.html#File-based_Configurations