是否有 getResources 的类似物,但使用定义为环境变量的项目外部路径?

Is there an analogue to getResources, but using a path outside the project defined as an environment variable?

我知道如果我想获得一个资源用于我的单元测试,我可以这样做:

String configPath = Objects.requireNonNull(
    TestResources.class
        .getClassLoader()
        .getResource("config.properties")).getPath();

我们还有一些资源位于环境变量中定义的路径中。对于这种情况,我们一直在做类似的事情:

String testDataPath = env.get("TEST_DATA")
String specificUseCase = Paths.get(testDataPath, "path", "to", "specific", "resource").toString();

在本例中,我使用了来自 TEST_DATA 的相对路径。有没有办法完全从图片中删除相对路径?

不要调用 URL 的 getPath() 方法。它不是 return 有效的文件名。如果 returned 资源 URL 指向包含 URL 中不允许的字符的文件路径,如空格,它们将是 percent-escaped.

无论如何,虽然理论上您可以创建自己的 URLClassLoader 来调用 getResource,但这样做没有意义。 getResource 和 getResourceAsStream 专门用于读取与应用程序捆绑的数据。

我看不出你使用 Paths.get 有什么问题。

I am concerned that the structure of the TEST_DATA directory will change and break my code. Is that something I should worry about?

是的,但使用 getResource 不会改变这一点。 getResource 实际上会更糟,因为如果找不到所需的资源,它只会 return null。当您从 Path 中读取时,您将得到一个信息异常(如 NoSuchFileException),而不仅仅是一个神秘的空值。

就其价值而言,Java 建议使用系统属性而不是环境变量来配置应用程序。系统属性必须明确设置,而不仅仅是用户忘记的登录初始化中的“遗留”内容。来自 the documentation of System.getenv:

System properties and environment variables are both conceptually mappings between names and values. Both mechanisms can be used to pass user-defined information to a Java process. Environment variables have a more global effect, because they are visible to all descendants of the process which defines them, not just the immediate Java subprocess. They can have subtly different semantics, such as case insensitivity, on different operating systems. For these reasons, environment variables are more likely to have unintended side effects. It is best to use system properties where possible. Environment variables should be used when a global effect is desired, or when an external system interface requires an environment variable (such as PATH).