当我将一些数据加载到我的java程序中时,我通常使用FileInputStream。但是我将程序部署为jar文件和webstart,所以我必须使用getRessource()或getRessourceAsStream()直接从jar文件加载数据。
现在总是在开发和部署之间切换这段代码非常烦人吗?
有没有这样的方法呢?即,有没有办法知道代码是否从jar运行?
当我尝试用这样的jar加载它时:
InputStream is = this.getClass().getResourceAsStream("file.txt");
返回的输入流只是null,尽管该文件肯定在应用程序的根目录中。
谢谢!
答案 0 :(得分:7)
为什么在开发过程中使用FileInputStream
?为什么不从一开始就使用getResourceAsStream
?只要将文件放在类路径中的适当位置,就不会有任何问题。它仍然可以是本地文件系统中的文件,而不是jar文件中的文件。
在考虑最终部署环境的情况下开发是有帮助的。
编辑:如果你想要类路径的 root 目录中的东西,你应该使用:
InputStream x = getClass().getResourceAsStream("/file.txt");
或
InputStream x = getClass().getClassLoader().getResourceAsStream("file.txt");
基本上Class.getResourceAsStream
将解析包含该类的包的相对资源; ClassLoader.getResourceAsStream
解析与“root”包相关的所有内容。
答案 1 :(得分:3)
您可以将您的数据始终作为资源阅读。您只需要将数据所在的路径添加到类路径中。
如果您的数据保留在jar文件中的WEB-INF/somewhere/mydata.txt
,您将使用以下命令访问它:
getClass().getResourceAsStream( "/WEB-INF/somewhere/mydata.txt" )
现在,如果您创建了一个开发目录/devel/WEB-INF/somewhere/mydata.txt
并将/devel
放到了类路径中,那么您的代码将在开发和生产中运行。
有问题的解释后编辑:
在您的情况this.getClass().getResourceAsStream( "mydata.txt" )
中,资源取自this
的类文件所在的相同位置。如果要保留此项,则必须创建目录/devel/<path of package>/mydata.txt
并再次将/devel
添加到类路径中。
答案 2 :(得分:0)
如何通过-D开关在开发环境中设置系统属性?例如java -D:mypropertyname = mypropertyvalue
您可以在开发环境中的ant脚本中设置属性,其他环境不会获取该属性: 例如
public static boolean isDevEnvironment(){ return System.getProperty("mypropertyname")!=null;}
您可能会从现有的System Properties
中找到一种更好的方法来破解它答案 3 :(得分:0)
如果文件被认为是已部署应用程序的一部分(而不是安装特定文件的一部分)并且可以通过类路径定位,那么请考虑简单地始终使用getResourceAsStream,因为无论实际部署方案如何,只要它可以工作它在类路径中。
您可能还会发现JVM提供的相关信息(如果安全管理员允许):
// Get the location of this class
Class cls = this.getClass();
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation(); // file:/c:/almanac14/examples/
http://www.exampledepot.com/egs/java.lang/ClassOrigin.html?l=rel
答案 4 :(得分:0)
开发与部署,IHMO之间应该没有任何区别。
Classloader.getResource或getResourceAsStream运行良好,您可以读取资源甚至编写它们。您可以编写自己的Protocol handles并访问所有内容作为URL / URI,这样您就可以读取和写入资源并允许正确识别实际提供资源的人。
唯一的问题是,如果URLStreamHandlerFactory已经注册(在J2EE应用程序中,容器可以安装工厂而您没有任何方法可以自行安装)并且您无法使用您的处理程序“随处”。
知道这一点,最好实现自己的“资源”。那时我需要它,我找不到那样的东西所以我必须实现自己的ResourceManager。对我来说,访问像
这样的资源看起来更直观Resource layout = ResourceManager.resolve("view://layout/main.jsp")
而不是
URL layout = Classloader.getResource("some_package/view/layout/main.jsp")