繁体   English   中英

Java EE中基于文件的安全数据持久性

[英]Safe file-based data persistance in Java EE

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

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

亲切的问候,q

真正做到这一点的唯一“安全”方法是依靠基础文件系统。

只是:

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);
}

这里发生的事情首先是我们将文件写入临时文件。 这可确保整个文件写入成功而不会损坏原始文件(例如,如果磁盘空间不足,原始文件将保留,因为此例程将无法完成)。 但是,如果此例程失败,则会保留延迟的临时文件,并且需要稍后进行清理。

一旦我们编写了文件,我们就强制操作系统清除对实际磁盘的任何挂起写入。 许多系统缓冲文件系统写入ram,并“最终”将它们写入磁盘。 这是出于明显的性能原因。 但是,如果系统在关闭文件和操作系统决定刷新写入之间崩溃或断电,则可能会丢失数据。 此同步是一种昂贵的操作。

最后,一旦我们确定我们已经编写了文件,并且它已经提交到磁盘(无论如何我们可以确定),然后我们将临时文件重命名为实际文件名。

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

此过程可确保以正确的名称完全“一次全部”更新文件。 该文件(在其正确的名称下)永远不会“部分存在”,如果您只是覆盖现有文件会发生这种情况。

最后,在Windows上,如果存在对原始文件的争用,则可能会出现问题,因为Windows不会删除由其他内容打开的文件。 Unix没问题,但是Windows却可以。 因此,在执行此重命名过程之前,您需要通过一些外部手段确保您可以单独访问该文件。

简短的回答是肯定的。 我实际上不得不做一个我曾经和一所大学做过的项目。 我在git枢纽上发布了代码: Speak To Me project 在该Web应用程序中,我将用户数据持久保存为纯文本格式,这样既便于人们阅读又易于对象重新初始化。

所以这个问题的读者可能想知道为什么我没有将数据库用于这些目的。 好吧,我与之共事的大学不想支持一所大学。 同样,此应用的流量非常低; 它是用于测试搜索界面的研究原型,因此它仅用于用户研究。 最后,由于应用程序的性质,持久保存文件使事情变得非常简单。 实际上,这些数据文件后来被用于后期研究分析。 此外,它还为那些不是优秀编码员的学生敞开了大门,让他们弄湿了脚(那……从未发生过)。

无论如何,我的建议是,如果你只是持久化简单的值,那么纯文本就可以了。 如果您的数据有任何复杂性,请使用JSON。 XML有点重量级,实际上只应在应用程序很大的情况下使用,但在那种情况下,您不应该坚持归档。

对于您的情况可能有点过分,但您可以使用HSQLDB 您可以将其配置为在文件中保留。

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

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

您可以使用Java中的可序列化接口来创建可以从磁盘保存和重新加载的持久对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM