如何跨目录读取类路径中的文本文件?

时间:2013-05-23 15:15:03

标签: java

我正在开发一个程序(使用JavaSE 1.6),该程序将从位于项目类路径中的文本文件中读取。

这些文件所在的文件夹与试图访问它们的类不同,并且将我的代码指向他们的位置让我感到困惑。

我正在运行的类位于“src / test / java”文件夹中的包中,而文本文件在“src / main / resources”文件夹中分成多个文件夹(用于组织目的)。

我目前正在尝试使用以下代码指向文本文件,但在行运行后,'in'会收到一个空值:

InputStream in = this.getClass().getResourceAsStream("/src/main/resources/<folder name here>/<file name here>.txt");

我不确定我是否可以指定这样的文件,如果它位于不同的目录中,所以我对如何继续进行了一点迷失......我搜索了Google和StackOverflow,发现了很多用于从类路径读取文件的资源,但没有关于如何将InputStream指向类的包外的文件。任何人都可以告诉我是否可能,如果是的话,怎么做?

4 个答案:

答案 0 :(得分:3)

实际答案完全取决于您如何构建/打包它。

看起来就像一个Maven项目,在这种情况下,src/xxx/yyy文件夹不在您的实际类层次结构中。构建后,src/main/resources将位于类路径的,这意味着类路径资源只是your/folders/and/file.txt

如果它一个Maven项目,那么这取决于你 构建它的方式。

答案 1 :(得分:1)

从您的路径中删除/src。假设src在您的构建路径上(在您的IDE中),那么编译后的代码将直接在根目录中包含其中的文件夹。例如,

/src
    /main/resources
        file.txt

将产生

/main/resources/file.txt

现在,如果构建路径中有/src/main/resources,则需要删除整个内容,文件将显示在根目录上。它的InputStream可以作为

访问
InputStream in = this.getClass().getResourceAsStream("/<folder name here>/<file name here>.txt");

实施例

/src/main/resources  // buildpath
    /spring
        applicationContext.xml
/src/main/java  // buildpath
    /mypackage
        MyClass.java

可以像

一样访问
InputStream in = this.getClass().getResourceAsStream("/spring/applicationContext.xml");

这意味着jar(如果你编译和打包它的方式)将被构造为

/spring
    applicationContext.xml
/mypackage
    MyClass.class

方法getResourceAsStream(String) javadoc说:

  
      
  • 如果名称以'/'('\ u002f')开头,则资源的绝对名称是'/'后面的名称部分。
  •   
  • 否则,绝对名称的格式如下:
      modified_pa​​ckage_name / name
  •   
     

其中modified_pa​​ckage_name是此对象的包名称,其中'/'替换为'。' ( '\ u002e')。

答案 2 :(得分:1)

对于同一个罐子,这个:

InputStream in = this.getClass()
    .getResourceAsStream("/<folder name here>/<file name here>.txt");

这可以使用相对于类包的相对路径,但这里是绝对的。

这样做(考虑Maven构建):

  • src/main/resources/<folder-path>/<file>下的源文件通常会复制到target/classes/<folder-path>/<file>。通常,IDE使用此路径进行内部运行。
  • 在构建时,/target/<project>.jar下会生成一个jar文件。
  • 使用7zip / WinZip打开该jar会显示<folder-path>/<file>

运行jar,路径区分大小写非常重要。

如果资源位于其他目录中

然后使用SystemClassLoader(包含所有类路径)。

InputStream in = ClassLoader
    .getSystemResourceAsStream("<folder name here>/<file name here>.txt");

这使用了我认为的绝对路径。这种用法可能会受益于具有(单个?)META-INF / INDEX.LIST(覆盖几个罐子)的罐子。

答案 3 :(得分:0)

通常,src不在您的类路径中。将路径更改为classes目录下的相应文件。