2012-01-03 51 views
1

是否有可能将Java EE应用程序(基于Spring Framework,运行于Tomcat容器中)保存在服务器上的文件中?Java EE中安全的基于文件的数据持久性

的情况如下:我有与int字段的一类(在启动过程中从读?)。我想以安全的方式将它保存到文件中(尽可能安全,这意味着幸存的服务器崩溃将不胜感激)。是否有可能(除了天真的文件读取/写入)

亲切的问候, q

回答

2

真的,唯一“安全”的方式就是依靠底层文件系统。

简单:

public void saveThing(Serializable thing, String fileName) throws Exception { 
    String tempFileName = fileName + "_tmp"; 
    File tempFile = new File(tempFileName); 
    FileOutputStream fos = new FileOutputStream(tempFile);   
    FileDescriptor fd = fos.getFD(); 
    ObjectOutputStream oos = new ObjectOutputStream(fos); 
    oos.writeObject(thing); 
    oos.flush(); 
    fd.sync(); 
    oos.close(); 
    f.renameTo(fileName); 
} 

这里发生的事情是第一次,我们正在写的文件到一个临时文件。这可确保整个文件写入成功,而不会损坏原始文件(例如,如果磁盘空间不足,原始文件将保留,因为此例程不会完成)。但是,如果此例程失败,临时存储的临时文件将保留,并且需要稍后清理。

一旦我们写的文件中,我们强制操作系统刷新任何未决写入实际的磁盘。许多系统将文件系统缓冲区写入内存,并“最终”将它们写入磁盘。这是显而易见的性能原因。但是,如果系统在关闭文件之间崩溃或断电,并且操作系统决定刷新写入,则可能会丢失数据。这个同步是一个昂贵的操作。最后,一旦我们确定我们已经写入了这个文件,并且它已经被提交到磁盘上了,那么我们就会将临时文件重命名为实际的文件名。

重命名文件系统上的文件是一个原子操作。它不能部分失败。它可以工作,也可以不工作。如果这两个文件位于同一个文件系统中,则重命名是即时的,因为它只是更新一些文件系统信息。如果两者位于不同的文件系统上,则必须先将新文件复制到新文件系统,然后重新命名。我假设这是如何完成的,我从来没有测试过。我倾向于坚持相同的文件系统并完全避免这个问题。

此过程确保文件将以正确的名称完全更新为“全部一次”。该文件(在其正确的名称下)不仅仅“部分存在”,如果您只是简单地覆盖现有文件,会发生什么情况。

最后,在Windows上,如果原始文件存在争用,您可能会遇到问题,因为Windows不会删除由其他内容打开的文件。这样做的Unix没有问题,但Windows确实如此。因此,您需要通过一些外部手段确保您在执行此重命名过程之前可以唯一访问该文件。

+0

这是一个答案!非常感谢你! – Queequeg 2012-01-05 07:16:52

0

这可能是矫枉过正上您的具体情况,但你可以使用HSQLDB。您可以将其配置为保留在文件中。

对于更简单的解决方案,您可以随时写入/读取文件。值得考虑的一些问题:

  • 使用JNDI或系统变量来存储文件的名称和路径。
  • 确保运行服务器的用户具有对该文件的读/写访问权限。
  • 以外,你可以使用标准的Java文件操作
0

您可以使用Java中serializable界面来创建可以保存和从盘重装持久对象。

+0

当然,我知道这一点。但我必须手动调用序列化方法。我想要它自己保存或smt。 simmilar。我想在服务器崩溃等情况下幸存下来。 – Queequeg 2012-01-03 14:50:01

+1

我在我的对象中实现了serializable,然后在启动服务器时读取了序列化对象,并将它们写入状态更改。我的要求是在战争文件的崩溃和重新部署中幸存下来,所以我必须确保磁盘上的序列化对象与服务器的当前状态一致。想想文件系统期刊是如何工作的,那就是你需要做的。 – 2012-01-03 15:15:41

+0

'写出他们对状态变化' - 你怎么接受这样的事件? – Queequeg 2012-01-05 07:13:48

1

简短的回答是肯定的。我实际上不得不为一个我刚刚在大学做过的项目做这件事。我在git集线器上发布了它的代码:Speak To Me project。在该Web应用程序中,我坚持将用户数据以纯文本格式保存起来,因此它既易于人类阅读,又易于让对象重新初始化自己。

所以这个问题的读者可能会奇怪,为什么我没有使用数据库用于这些目的。那么我与之合作的大学不想支持一个。此外,这款应用的流量非常低,它是测试搜索界面的研究原型,因此仅用于用户研究。最后,由于应用程序的性质,坚持文件保持非常简单。事实上,这些数据文件后来被用于后期研究分析。此外,它还为不擅长编程的学生敞开了脚步(从未发生过)。

总之,我的建议是,如果你只是简单的持久价值,那么纯文本将被罚款。如果您的数据具有任何复杂性,请使用JSON。 XML有点重量级,只有在你的应用程序很大时才应该使用,但在这种情况下,你不应该坚持文件。

+0

谢谢你的回答! – Queequeg 2012-01-05 07:12:45