我的Java应用程序在名为“assets”的顶级文件夹中有一个名为“classes”(简单{@iterate items="ab,cd,ef,12"}
Item: {.}{~n}
{/iterate}
)的本地文件。当我从Eclipse运行下面的代码时,文件读取没问题。
{#iterate}
当我将我的应用程序导出为JAR并在另一台计算机上运行时,我在第3行获得List<String>
。我将“assets”文件夹添加到构建路径中,因此它应该在JAR中。
有人知道这里有什么问题吗?
答案 0 :(得分:1)
FileOutputStream
只会打开一个本地文件。它应该是绝对的(/home/user/...
或c:\temp\...
)或相对于当前目录。例如,在Windows上,默认情况下,该目录是包含JAR的目录。
如果您打算将classes
文件打包到 JAR中,那么您应该使用getResourceAsStream
,如@guleryuz所述。该路径应该是从CLASSPATH根(即JAR文件的根)开始的绝对路径,如"/assets/classes"
,或者(更好)相对于调用类的包。
说到课程,我强烈反对使用getClass()
,因为它是一种多态方法。获取类有两种方法:通过在对象上调用getClass()
或访问静态class
“字段”。如果您的MyClass
实例名为myObject
,则myObject.getClass()
和MyClass.class
基本相同。但!如果您的课程被其他论坛中的某个课程覆盖,例如TheirClass
,那么,对于TheirClass
的实例,getClass()
将返回TheirClass.class
,即使您正在呼叫来自您的代码的getClass()
。因此,除非您的班级被声明为final
,否则使用getClass().getResource...
总是一个坏主意,因为您永远不知道有人会超越您的班级。你不应该知道甚至不关心!
考虑到所有这些,比如说,你在名为MyClass
的包中有一个名为my.package
的类。 JAR可以具有以下结构:
my/
package/
MyClass.class
assets/
classes
然后,调用MyClass.class.getResourceAsStream("assets/classes")
就可以了。或者,可能是MyClass.class.getResourceAsStream("/my/package/assets/classes")
。请注意,绝对路径 not 从项目目录开始,您可能在其中src
或src/main
或您的构建系统使用的任何内容。它是相对于CLASSPATH根(右边,绝对路径相对到CLASSPATH根目录,即使这看起来很混乱)。也就是说,它从包的目录开始。
最后但并非最不重要的是,如果您使用类似Maven的构建系统(例如Maven或Gradle),那么Java源代码将转到src/main/java
,但是像您的文件这样的资源文件会转到{{ 1}}。它们最终位于JAR文件中的完全相同的位置。也就是说,src/main/resources
被编译为src/main/java/package/MyClass.java
,package/MyClass.class
进入src/main/resources/package/assets/classes
。但是为了让构建系统弄清楚如何处理文件,您必须将它们放在正确的目录中:package/assets/classes
转到*.java
,资源转到java
。
因此,假设类似Maven的约定,项目结构应该是
resources
鉴于这样的结构,您将获得具有上述结构的JAR文件。看起来有点疯狂,但是一旦掌握了它就非常有用。
如果您没有使用类似Maven的构建系统,那么我不知道如何配置Eclipse。不同的IDE可能有自己的约定,我总是使用Maven和Eclipse。例如,有些IDE喜欢将Java源代码和资源放在同一个目录树中。