【问题标题】:getResourceAsStream() - InputStream null when using relative pathgetResourceAsStream() - InputStream 使用相对路径时为空
【发布时间】:2015-07-03 14:35:39
【问题描述】:

我正在使用 Maven 并在尝试使用以下方式读取文件的静态方法上运行 JUnit 测试:

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename);

然后使用new InputStreamReader(is) 在另一个调用中用作阅读器。当filename 只是一个文件名(例如file.csv)但当filename 是一个相对路径(例如src/test/resources/file.csv)时,这有效,is 最终是null

我需要它来处理相对路径,因为我正在通过 JUnit 运行一个测试套件,它查找具有相对路径的资源,并且这些测试来自我无法控制更改的 JAR(即我实现了外观实现测试套件使用自己的资源调用自己的测试的类 - 它们不在我的控制范围内)。

有没有办法让这种方法使用相对路径,或者我可以通过其他方式在我的类路径上找到测试正在寻找的那些资源?

【问题讨论】:

  • 尝试删除 src 并从 /test 开始。
  • 这只是一个通用示例。我将无法更改输入的路径,因为它们位于我无法更改的测试套件中。希望将所需的资源放在我的类路径中,然后代码将在创建 InputStream 时适当地找到它们。
  • 它们与我的内部文件系统无关(这就是我不能使用 File 和 FileReader 的原因),它们是在 Maven 接受的 JAR 依赖项中定义的相对路径。

标签: java maven junit inputstream relative-path


【解决方案1】:

在 maven 中运行测试,src/test/resources/(默认情况下)“映射”到类(加载器)路径的 root,所以在你的情况下,/file.csv 是正确的 src/test/resources/file.csv 的绝对路径

要成功加载"src/test/resources/file.csv"(资源)(这是完全废话),您应该(物理上)提供此文件:src/test/resources/src/test/resources/file.csv,或分别为src/main/java(这也将是映射到 cp 根).../src/test/resources/file.csv

【讨论】:

  • 将代码放在自己的方法中不会解决任何问题。它仍然只是返回 null。
【解决方案2】:

我在博客上有这个(西班牙语)

http://lacuevadeyogui.blogspot.com/2015/04/diferencia-entre-uri-y-url.html

在 src/test/resources 中引用文件的问题

试试这个

URL url = getClass().getClassLoader().getResource("file.csv");
File f;
try {
    f = new File(url.toURI());
} catch (URISyntaxException e) {
    f = new File(url.getPath());
}

最后,将文件转换为输入流。

【讨论】:

    【解决方案3】:

    在您的情况下,is 最终为 null,因为在执行资源查找时,resources 目录是入口点,因此完整路径应为 test/resources/src/test/resources/file.csvtest/resources/src/test/resources/file.csv,具体取决于您的运行方式你的测试。

    实现目标的唯一可靠方法是手动注意正确性。也许是这样的:

    static String getResourceFileName(String maybePath) {
        Path path = Paths.get(maybePath);
        if (path.getNameCount() > 0) {
            return path.getFileName().toString();
        } else {
            throw new IllegalArgumentException("Can't derive filename given " + maybePath);
        }
    }
    
    @Test
    public void testSoq() throws Exception {
        String fileName0 = getResourceFileName("file");
        InputStream is0 = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName0);
    
        String fileName1 = getResourceFileName("src/test/resources/file");
        InputStream is1 = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName1);
        String string0 = new BufferedReader(new InputStreamReader(is0)).readLine();
        String string1 = new BufferedReader(new InputStreamReader(is1)).readLine();
        assertEquals(string0, string1); // OK
    }
    

    也许您必须根据您的案例的具体情况编写它(考虑可能的嵌套目录等),但我真的认为鉴于您的输入可能具有任意性质,这不会变得更简单。

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2011-12-03
      • 2019-04-22
      • 2017-11-13
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2018-02-22
      相关资源
      最近更新 更多