我想知道如何从EJB 3 bean访问文件系统?
我在互联网上搜索了这个主题,并没有找到一个好的答案。
有人建议使用java.io/java.nio,即使规范禁止此用法。大多数应用程序服务器似乎都允许访问此API。
另一个想法是使用JCA连接器访问文件系统或LDAP目录。
我想这样做是为了避免在简单文件在性能和使用资源方面更好的解决方案时在数据库中使用BLOB。
你会如何解决这个问题?
答案 0 :(得分:9)
您在EJB中对文件系统访问不允许的原因是您无法控制应用程序在(Java EE) Container 中的运行方式。例如,您的应用程序可能跨服务器集群运行,在这种情况下,将某个对象保存到一台服务器上的目录可能没什么用处。 (当然,您可能有网络文件系统,因此限制可能不适用。)
一种选择可能是使用 容器附带的 JNDI 实施。您可能能够在某个JNDI位置保存原始byte[]
数组,因此您可以始终保存对象的序列化形式:
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 (即XMLDecoder
,XMLEncoder
)将您的实例编码为XML字符串,并将其保存到JNDI中。
答案 1 :(得分:7)
如果您知道永远不会集中您的应用程序(或者您将能够对驱动器进行网络映射),那么只需使用java.io。*。
请务必引入有关文件存储的根位置的正确配置。
答案 2 :(得分:5)
封装您对文件数据的访问权限。然后你可以使用上面列出的任何方法。甚至使用数据库。衡量系统的性能。如果它符合要求那么你就完成了。如果不是,您的文件访问权限已在一个位置本地化,您可以替换其他解决方案。如果必须将软件移植到另一个容器和/或必须由其他人维护,则具有相同的好处。
答案 3 :(得分:1)
纯文件访问本质上不是事务性的。除非你建立对事务操作的支持(我对如何 - 这是资源管理器的工作一无所知),否则你将不得不担心正在执行的操作的事务语义。如果你确实构建了事务支持,那么你在性能上几乎没有获得(数据库性能的一些损失,是由于资源管理器完成的所有簿记)。 并且不要忘记事务管理的近亲 - 并发。除非你开始为每个请求写入一个新文件,否则并发问题或多或少会让你感到厌烦。
您可以在Sun Blueprint's FAQ on EJB restrictions找到更多信息。
除非您有明确的技术理由,否则不应尝试从EJB访问文件系统。一个非常好的例子,是一个日志记录(不是审计)框架 - 访问文件系统写日志文件的危害相对较小,因为日志记录不一定是事务操作,即你不需要回滚写入日志文件;并不是说部分写入是可以接受的。