简体   繁体   English

getResourceAsStream() - InputStream 使用相对路径时为 null

[英]getResourceAsStream() - InputStream null when using relative path

I am using Maven and running a JUnit test on a static method that tries to read in a file using:我正在使用 Maven 并在尝试使用以下方法读取文件的静态方法上运行 JUnit 测试:

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

And then using new InputStreamReader(is) to use as a reader in another call.然后使用new InputStreamReader(is)在另一个调用中用作读取器。 This works when filename is just a filename (eg file.csv ) but when filename is a relative path (eg src/test/resources/file.csv ), is ends up being null .这个作品时, filename只是一个文件名(如file.csv ),但是当filename是相对路径(例如src/test/resources/file.csv ), is最终被null

I need it to handle relative paths, because I'm running a test suite via JUnit that looks for resources with relative paths and these tests are coming from a JAR that I have no control over changing (ie I implemented a facade implementation class that the test suite uses to call its own tests with its own resources - they are out of my control).我需要它来处理相对路径,因为我正在通过 JUnit 运行一个测试套件来查找具有相对路径的资源,而这些测试来自一个我无法控制更改的 JAR(即我实现了一个外观实现类测试套件使用自己的资源调用自己的测试 - 它们不受我的控制)。

Is there a way for this approach to work with relative paths, or some other way that I can find those resources on my classpath that the tests are looking for?有没有办法让这种方法与相对路径一起工作,或者我可以通过其他方式在我的类路径上找到测试正在寻找的资源?

Running tests in maven, src/test/resources/ is (by default) "mapped" to the root of the class(loader)path, so in your case /file.csv is the correct absolute path of src/test/resources/file.csv .在 maven 中运行测试, src/test/resources/ (默认情况下)“映射”到类(加载器)路径的,所以在你的情况下/file.csvsrc/test/resources/file.csv的正确绝对路径src/test/resources/file.csv

To load "src/test/resources/file.csv" (Resource) successfully ( which is comple nonsense ), you should have this file (physically) available: src/test/resources/src/test/resources/file.csv , or respectively src/main/java (which would also be mapped to cp root) ... /src/test/resources/file.csv要成功加载"src/test/resources/file.csv" (资源)(完全是废话),你应该有这个文件(物理上)可用: src/test/resources/src/test/resources/file.csv ,或分别为src/main/java (也将映射到 cp root)... /src/test/resources/file.csv

In your case is ends up being null because when a resource lookup is performed, the resources directory is entry point, so the complete path is expected to be test/resources/src/test/resources/file.csv or test/resources/src/test/resources/file.csv depending on how you run your tests.你的情况is最终被空,因为当进行资源查找,该resources目录的切入点,所以完整的路径有望成为test/resources/src/test/resources/file.csvtest/resources/src/test/resources/file.csv取决于您如何运行测试。

The only reliable way you could achieve your goal is to take care about the correctness manually.您可以实现目标的唯一可靠方法是手动注意正确性。 Perhaps something like this:也许是这样的:

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
}

Maybe you'll have to write it according to the specifics of your case (account for possible nested diretories etc.), but I really think that given your inputs may be of arbitrary nature, this won't get much simpler.也许您必须根据您的案例的具体情况(考虑可能的嵌套目录等)来编写它,但我真的认为鉴于您的输入可能具有任意性质,这不会变得更简单。

I have this on blog (in spanish)我在博客上有这个(西班牙语)

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

The problem in with the reference to file in src/test/resources引用 src/test/resources 中的文件的问题

try this尝试这个

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

At the end, convert file to inputStream.最后,将文件转换为 inputStream。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM