如何在Java中高效地管理文件系统?

3
我正在创建一些JAX-WS端点,并希望保存接收和发送的消息以供以后检查。为此,我计划将消息(XML文件)保存到文件系统中,以某种合理的层次结构组织。每天可能会有数百甚至数千个文件。我还需要为每个文件存储元数据。
我考虑将元数据(只有几个字段)放入数据库表中,但将XML文件内容本身存储在文件系统中的文件中,以避免使数据库因内容数据(很少读取)而膨胀。
是否有一些简单的库可以帮助我保存、加载、删除等文件?实现它自己并不那么棘手,但我想知道是否存在现有的解决方案?只需一个简单的库,已经提供对文件系统的易于访问(最好跨不同操作系统)。
或者我是否真的需要它,应该使用原始/自定义Java?
2个回答

6

是否有一些简单的库可以帮助我保存、加载、删除文件等操作?虽然自己实现不是很复杂,但我想知道是否已经存在解决方案了?只需要一个简单的库,可以提供易于访问的文件系统(最好能在不同操作系统上使用)。

Java API

如果您需要做的事情确实很简单,您应该可以通过java.io.File(删除、检查文件是否存在、读取、写入等)和几个流操作FileInputStreamFileOutputStream来实现您的目标。

您还可以加入Apache commons-io及其方便的FileUtils,以获取更多实用功能。

Java独立于操作系统。您只需要确保使用File.pathSeparator或使用构造函数File(File parent, String child),以便无需显式地提到分隔符。

Java文件API相对高级,可抽象出许多操作系统之间的差异。大多数情况下已经足够了。仅当您需要一些相对操作系统特定的功能而不在API中时,它才有一些缺点,例如检查磁盘上文件的物理大小(而不是逻辑大小)、*nix上的安全权限、硬盘的可用空间/配额等。

大多数操作系统都有一个用于文件读写的内部缓冲区。使用 FileOutputStream.writeFileOutputStream.flush 可以确保数据已经发送到操作系统,但不一定写入磁盘。Java API 也支持这种低级集成来管理这些缓冲问题(例如 此处)以用于数据库等系统。
同时,文件和目录都是用 File 抽象出来的,并且需要通过 isDirectory 进行检查。这可能会令人困惑,例如如果你有一个文件 x 和一个目录 /x(我不记得如何处理这个问题,但有一种方法)。 Web 服务 Web 服务可以使用 xs:base64Binary 来传递数据,或者如果文件很大,则使用 MTOM(消息传输优化机制)。 事务 请注意,数据库是事务性的,文件系统不是。因此,如果操作失败并且需要重试,您可能需要添加一些检查。您可以选择一个涉及某种形式的分布式事务的复杂设计(请参见此答案),或者尝试使用提供所需强度水平的简单设计。一个可能的设计如下:
- 更新。如果用户想要覆盖一个文件,实际上会创建一个新文件。逻辑文件名和物理文件之间的间接级别存储在数据库中。这样,一旦写入物理文件,就永远不会覆盖它,以确保回滚一致。 - 创建。当用户想要创建一个文件时,情况相同。 - 删除。如果用户想要删除一个文件,则首先只在数据库中执行此操作。定期作业轮询文件系统以识别未列在数据库中的文件,并将其删除。这两个阶段的删除确保可以回滚删除操作。
这种方式不像在真实的事务性数据库中编写BLOB那样健壮,但是还是提供了一定的鲁棒性。你也可以查看commons-transaction,但我觉得这个项目已经死亡了(2007年)。

一个扎实的答案,谢谢。我应该猜到Apache Commons也有一些对这个问题的贡献!我必须承认,我对高级文件处理Java API感到有些惊讶 - 我原本期望会有更低级别的东西。我认为你的指针足以让我开始和完成这个任务。然而,你提到的事务点非常相关。是否可能将文件系统操作绑定到同一事务中(并回滚)? - Tuukka Mustonen
@Tukka Mustonen,我添加了一些更多的细节。 据我所知,很遗憾无法轻松地绑定文件系统和数据库。 然而,我已经描述了一种可能的方式来提高健壮性,而不引入复杂的分布式事务。 - ewernli
感谢您详细解答。我认为您建议的将文件系统操作与数据库事务绑定的方法足够简单,但非常可行。由于还没有其他答案,我选择这个作为被接受的答案,并将走这条路。我仍然很想知道是否有任何项目将所有这些东西绑定在一个更高级别的API后面,提供事务和版本支持,合理的文件/目录结构,对文件元数据的支持,异常转换/处理,并且通常照顾我无法预见的事情 :) 有人知道吗? - Tuukka Mustonen
@Tuukka Mustonen,有两个:JSR-170和JSR-283。您也可以看一下Apache Jackrabbit。但是我认为您现在询问的不仅仅是一个简单的API来保存、加载和删除文件,而是一个文档管理API :) - ewernli
1
关于在单个事务中绑定文件系统和数据库操作,可以使用XA事务。由于文件系统通常不支持XA,因此可以依赖于XADisk(http://xadisk.java.net/)。 - Nitin Verma
@NitinVerma 不错,我也开始做这样的项目了http://code.google.com/p/txfs/,但你的似乎更为成熟。 - ewernli

0

有一个Java持久化提供者DataNucleus。它对于这种情况来说有点过重,但它支持不同的数据存储(RDBMS、对象存储、XML、JSON、Excel等)和JPA、JDO Java标准。如果产品已经使用JPA或JDO,考虑使用NataNucleus可能是值得的,因为将数据保存到不同的数据存储应该是透明的。我猜测DataNucleus支持将数据拆分成多个文件,并创建我想要的合理的目录/文件结构(在我的问题中),但这只是一个猜测。

XML和JSON的支持似乎是实验性的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接