我想从我的罐子里像这样读一个资源:

File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferedReader reader = new BufferedReader(new FileReader(file));

//Read the file

当在Eclipse中运行它时,它工作得很好,但如果我将它导出到一个jar,然后运行它,会有一个IllegalArgumentException:

Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical

我真的不知道为什么,但通过一些测试,我发现如果我改变了

file = new File(getClass().getResource("/file.txt").toURI());

to

file = new File(getClass().getResource("/folder/file.txt").toURI());

然后它反过来工作(它在jar中工作,但在eclipse中不工作)。

我正在使用Eclipse,文件所在的文件夹位于类文件夹中。


当前回答

与其试图将资源定位为File,不如让ClassLoader通过getResourceAsStream为资源返回一个InputStream:

try (InputStream in = getClass().getResourceAsStream("/file.txt");
    BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
    // Use resource
}

只要file.txt资源在类路径上是可用的,那么无论file.txt资源是在classes/目录中还是在jar中,这种方法都会以同样的方式工作。

URI不是分层的,因为jar文件中资源的URI看起来像这样:file:/example.jar!/file.txt。您不能像读取普通的旧文件一样读取jar (zip文件)中的条目。

以下问题的答案很好地解释了这一点:

如何从Java jar文件中读取资源文件? Java Jar文件:使用资源错误:URI不是分层的

其他回答

下面的代码使用Spring引导(kotlin):

val authReader = InputStreamReader(javaClass.getResourceAsStream("/file1.json"))

与其试图将资源定位为File,不如让ClassLoader通过getResourceAsStream为资源返回一个InputStream:

try (InputStream in = getClass().getResourceAsStream("/file.txt");
    BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
    // Use resource
}

只要file.txt资源在类路径上是可用的,那么无论file.txt资源是在classes/目录中还是在jar中,这种方法都会以同样的方式工作。

URI不是分层的,因为jar文件中资源的URI看起来像这样:file:/example.jar!/file.txt。您不能像读取普通的旧文件一样读取jar (zip文件)中的条目。

以下问题的答案很好地解释了这一点:

如何从Java jar文件中读取资源文件? Java Jar文件:使用资源错误:URI不是分层的

如果你想读取一个文件,我相信仍然有一个类似的解决方案:

    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("file/test.xml").getFile());

如果你正在使用spring,那么你可以使用下面的方法从src/main/resources中读取文件:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.springframework.core.io.ClassPathResource;

  public String readFileToString(String path) throws IOException {

    StringBuilder resultBuilder = new StringBuilder("");
    ClassPathResource resource = new ClassPathResource(path);

    try (
        InputStream inputStream = resource.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) {

      String line;

      while ((line = bufferedReader.readLine()) != null) {
        resultBuilder.append(line);
      }

    }

    return resultBuilder.toString();
  }

就我而言,我终于做到了

import java.lang.Thread;
import java.io.BufferedReader;
import java.io.InputStreamReader;

final BufferedReader in = new BufferedReader(new InputStreamReader(
      Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt"))
); // no initial slash in file.txt