java 如何从 EJB 3 访问文件系统?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1357667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access the file system from an EJB 3?
提问by Pierre Thibault
I would like to know how can I access the file system from an EJB 3 bean?
我想知道如何从 EJB 3 bean 访问文件系统?
I searched the Internet on the subject and haven't found a good answer.
我在互联网上搜索了这个主题,但没有找到好的答案。
Some suggest using the java.io/java.nio even though the specification prohibits this usage. Most application servers seem to allow the access to this API anyway.
有些人建议使用 java.io/java.nio,即使规范禁止这种用法。大多数应用服务器似乎都允许访问这个 API。
Another idea would be to use an JCA connector to access the file system or a LDAP directory.
另一个想法是使用 JCA 连接器来访问文件系统或 LDAP 目录。
What I want to do this to avoid the use of BLOB in the database when a simple file would be a much better solution in terms of performance and used resources.
我想这样做是为了避免在数据库中使用 BLOB,因为就性能和使用的资源而言,一个简单的文件将是一个更好的解决方案。
How would you solve this problem?
你会如何解决这个问题?
回答by oxbow_lakes
The reason that you are disallowedfrom file system access in EJBs is that you have no control over how your application runs within a (Java EE) Container. For example, your application may be run across a cluster of servers, in which case saving some object to a directory on one server is likely to be of little use. (You may have a network file-system of course, so the restriction may not apply).
不允许您在 EJB 中访问文件系统的原因是您无法控制应用程序在 (Java EE) Container 中的运行方式。例如,您的应用程序可能在一组服务器上运行,在这种情况下,将某个对象保存到一台服务器上的目录中可能没有多大用处。(当然,您可能有网络文件系统,因此该限制可能不适用)。
One option may be to usethe JNDIimplementation which comes with your Container. You will likely be able to save a raw byte[]array at some JNDI location, so you could always save down the serialized form of the object:
一种选择可能是使用您的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());
This can be looked up later and re-converted into your object:
这可以稍后查找并重新转换为您的对象:
byte[] bs = (byte[]) new InitialContext().lookup("path/to/myobject");
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bs));
MyObj myObj = (MyObj) ois.readObject();
Alternatively you could use the java.beanspersistent XML(i.e. XMLDecoder, XMLEncoder) to encode your instance as an XML string an save that into JNDI.
或者,您可以使用java.beans持久性 XML(即XMLDecoder, XMLEncoder)将您的实例编码为 XML 字符串并将其保存到 JNDI 中。
回答by flybywire
If you know you will never cluster your application (or that you will be able to network-map the drive) then just use java.io.*.
如果您知道您永远不会集群您的应用程序(或者您将能够对驱动器进行网络映射),那么只需使用 java.io.*。
Be sure to introduce proper configuration regarding the root location of your files storage.
请务必对文件存储的根位置进行适当的配置。
回答by Conor
Encapsulate your access to file data. Then you could use any of the methods outlined above. Even use a database. Measure the performance of your system. If it meets requirements then you are done. If not your file access is localised in one place and you can substitute a different solution. Same benefit if the software has to be ported to another container and/or has to be maintained by someone else.
封装您对文件数据的访问。然后,您可以使用上述任何一种方法。甚至使用数据库。测量系统的性能。如果它满足要求,那么你就完成了。如果不是,您的文件访问是在一个地方本地化的,您可以替换为不同的解决方案。如果软件必须移植到另一个容器和/或必须由其他人维护,则同样有好处。
回答by Vineet Reynolds
Plain file access is not transactional in nature. Unless you build in support for transactional operations (I'm clueless on how - this is the job of a resource manager), you will have to worry about transactional semantics of the operation that you are performing. If you do build in transaction support, there is very little you would have gained in performance (some of the loss in performance in databases, is due to all the bookkeeping done by the resource manager). And don't forget transaction management's close cousin - concurrency. Unless you start writing into a new file for every request, concurrency issues will more or less bite you.
普通文件访问本质上不是事务性的。除非您内置对事务操作的支持(我对如何操作一无所知 - 这是资源管理器的工作),否则您将不得不担心您正在执行的操作的事务语义。如果您确实内置了事务支持,那么您在性能上的收益将非常小(数据库性能的一些损失是由于资源管理器完成的所有簿记)。并且不要忘记事务管理的近亲——并发。除非您开始为每个请求写入一个新文件,否则并发问题或多或少会困扰您。
You will find a lot more information in the Sun Blueprint's FAQ on EJB restrictions.
您可以在Sun Blueprint 关于 EJB 限制的常见问题解答中找到更多信息。
Unless you are in the clear with a good technical justification, you should not attempt to access the filesystem from EJBs. A very good example, would be a logging (not auditing) framework - there is relatively less harm in accessing the file system to write log files, given that logging does not have to be a transaction operation i.e. you dont need to rollback writes to a logfile; not that it is acceptable to have partial writes.
除非您有充分的技术理由,否则您不应尝试从 EJB 访问文件系统。一个很好的例子是日志(不是审计)框架 - 访问文件系统以写入日志文件的危害相对较小,因为日志不必是事务操作,即您不需要回滚写入日志文件;并不是说部分写入是可以接受的。

