如何加载相对于 class 包的文件?

How can I load a file relative to a class's package?

我在名为 fixtures 的子目录中有文件 allDepartments.json,我想从 Fixture.java class.

访问该文件

这是我的 Fixture.java 代码:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public final class Fixture {
    private static final String FIXTURES_PATH = "";
    private final String fixture;

    public Fixture(String fixtureName) throws IOException {
        fixture = new String(Files.readAllBytes(Paths.get(FIXTURES_PATH + fixtureName)));
    }

    public final String getFixture() {
        return fixture;
    }
}

然而,每次他尝试访问该文件时,我都会收到 java.nio.file.NoSuchFileException: allDepartments.json...

我听说过 getResource() 方法并尝试了所有可能的组合,但没有成功。

我需要它来为我的 JUnit 测试存储多行字符串。

我能做什么?

allDepartments.json添加到项目的.classpath文件中,java应该可以提取它。

想知道的可以参考这个话题how to add a file to class path from eclipse

当您 运行 Fixtures.java 时,相对路径将是

../fixtures/allDepartments.json

尝试使用此路径。

NIO.2 API 不能用于读取有效项目资源的文件,即存在于 class 路径上的文件。

在您的情况下,您有一个 Maven 项目和一个资源,您希望在应用程序的单元测试期间阅读这些资源。首先,这意味着此资源应放在 src/test/resources 下,以便 Maven 在测试期间自动将其添加到 class 路径。其次,这意味着您不能使用 Files 实用程序来读取它。

您将需要使用传统的 BufferedReader:

public Fixture(String fixtureName) throws IOException {
    try (BufferedReader br = new BufferedReader(new InputStreamReader(Fixture.class.getResourceAsStream(FIXTURES_PATH + fixtureName)))) {
        // do your thing with br.readLine();
    }
}

请注意,给 getResourceAsStream 的路径是相对于当前 class 的路径或绝对路径。如果资源位于 src/test/resources/folder/allDepartments.json 中,则有效路径为 /folder/allDepartments.json.

感谢大家的帮助和建议。

多亏了你,我才能够正常工作,所以这是技巧(我想这只适用于 Maven 项目):

我按照你们的建议将 allDepartments.json 文件移到了默认的 src/test/resources 文件夹。我什至不必修改 pom.xml。现在一切正常!

现在这是我的项目结构:

最后的Fixture.java代码是:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.stream.Collectors;

public final class Fixture {
    private final String fixture;

    public Fixture(String fixtureName) throws IOException {
        fixture = this.readFile(fixtureName);
    }

    private String readFile(String fileName) throws IOException {
        final InputStream in = this.getClass().getClassLoader().getResource("fixtures/" + fileName).openStream();
        final BufferedReader buffer = new BufferedReader(new InputStreamReader(in));
        try {
            return buffer.lines().collect(Collectors.joining("\n"));
        } finally {
            buffer.close();
        }
    }

    public final String getFixture() {
        return fixture;
    }
}