在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

从头开始制作非常简单。 你可以这样说:

  1. 有一个DB(或只是一个文件)存储处理进度的信息。 就像是:

      Id|fileName|status|metadata 
  2. 一旦开始处理文件,就立即输入该表。 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