如何从EJB 3访问文件系统?

我想知道如何从EJB 3 bean访问文件系统?

我在互联网上搜索了这个主题,并没有找到一个好的答案。

有人建议使用java.io/java.nio,即使规范禁止这种用法。 大多数应用程序服务器似乎都允许访问此API。

另一个想法是使用JCA连接器来访问文件系统或LDAP目录。

我想这样做是为了避免在数据库中使用BLOB,因为在性能和使用的资源方面,简单文件是一个更好的解决方案。

你怎么解决这个问题?

不允许在EJB中访问文件系统的原因是您无法控制应用程序在(Java EE) 容器中的运行方式 。 例如,您的应用程序可能跨服务器集群运行,在这种情况下,将某个对象保存到一台服务器上的目录可能没什么用处。 (当然,您可能拥有网络文件系统,因此限制可能不适用)。

一种选择可能是使用 Container附带的JNDI实现。 您可能能够在某个JNDI位置保存原始byte[]数组,因此您可以始终保存对象的序列化forms:

 ByteArrayOutputStream baos= new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(myObj); //Now save into JNDI new InitialContext().bind("path/to/myobject", baos.toByteArray()); 

这可以在以后查找并重新转换为您的对象:

 byte[] bs = (byte[]) new InitialContext().lookup("path/to/myobject"); ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bs)); MyObj myObj = (MyObj) ois.readObject(); 

或者,您可以使用java.beans 持久性XML (即XMLDecoderXMLEncoder )将您的实例编码为XML字符串,并将其保存到JNDI中。

如果您知道永远不会集中应用程序(或者您将能够对驱动器进行网络映射),那么只需使用java.io. *即可。

请务必引入有关文件存储的根位置的正确配置。

封装您对文件数据的访问权限。 然后你可以使用上面列出的任何方法。 甚至使用数据库。 衡量系统的性能。 如果它符合要求那么你就完成了。 如果不是您的文件访问权限在一个地方本地化,您可以替换其他解决方案。 如果必须将软件移植到另一个容器和/或必须由其他人维护,则具有相同的好处。

纯文件访问本质上不是事务性的。 除非你建立对事务操作的支持(我对如何 – 这是资源管理器的工作一无所知),否则你将不得不担心正在执行的操作的事务语义。 如果您确实构建了事务支持,那么您在性能方面所获得的收益很少(数据库性能的一些损失,是由于资源管理器完成的所有簿记)。 并且不要忘记事务管理的近亲 – 并发。 除非您开始为每个请求写入新文件,否则并发问题或多或少会让您感到困惑。

您可以在Sun Blueprint的EJB限制常见问题解答中找到更多信息。

除非您有明确的技术理由,否则不应尝试从EJB访问文件系统。 一个非常好的例子,是一个日志记录(不是审计)框架 – 访问文件系统来写日志文件的危害相对较小,因为日志记录不一定是事务操作,即你不需要回滚写入日志文件; 并不是说部分写入是可以接受的。