以编程方式在java的资源/源文件夹中创建文件?

2022-09-02 04:18:14

我有两个资源文件夹。

src - 这是我.java文件

资源 - 这是我的资源文件(图像,.属性)组织在文件夹(包)中。

有没有办法以编程方式在该资源文件夹中添加另一个 .properties 文件?

我尝试了这样的东西:

public static void savePropertiesToFile(Properties properties, File propertiesFile) throws IOException {
        FileOutputStream out = new FileOutputStream(propertiesFile);
        properties.store(out, null);
        out.close();
    }

在此之前创建:

new File("/folderInResources/newProperties.properties");

但它会在文件系统上查找该路径。如何强制它在资源文件夹中查找?

编辑:让我说说它是什么。我有一个GUI应用程序,我支持2种语言(资源文件夹中的2个.properties文件)。现在我添加了一个选项,用户可以轻松地翻译应用程序,当他完成时,我将新的.properties保存在磁盘上的某个隐藏文件夹中,并从那里读取它。但我希望我能将新的.properties文件(新语言)保存在当前语言(资源文件夹)旁边。我有一个静态 Messages 类,它知道如何从磁盘加载资源,以及如何从资源文件夹中加载默认资源。但是,如果用户在其他计算机上将此.jar文件,他就不会有该新语言,因为它们位于该计算机上的磁盘上,而不是.jar文件中。


答案 1

Java 8 解决方案

 Path source = Paths.get(this.getClass().getResource("/").getPath());
        Path newFolder = Paths.get(source.toAbsolutePath() + "/newFolder/");
        Files.createDirectories(newFolder);

这肯定会在资源文件夹中创建新文件夹。但是您将在目标运行时中找到新文件夹。

这将是.如果在测试用例中运行此代码。其他明智的做法是ProjectName/target/test-classes/newFoldertarget/classes

不要尝试在 .它肯定会在 或 中。src/resourcestarget/test-classestarget/classes


答案 2

正如其他人所提到的,资源是通过 ClassLoader 获取的。然而,目前的两个回应没有强调的是以下几点:

  • 类加载器旨在抽象获取类和其他资源的过程。资源不必是文件系统中的文件;它可以是一个远程URL,或者您或其他人可以通过扩展来实现的任何内容。java.lang.ClassLoader
  • 类加载器存在于子/父委派链中。类加载器的正常行为是首先尝试从父级获取资源,然后才搜索自己的资源 — 但某些类装入器执行相反的顺序(例如,在 servlet 容器中)。在任何情况下,你都需要确定哪个类加载器的位置来获取你想要将内容放入其中,即使这样,它上面或下面的另一个类加载器可能会“窃取”客户端代码的资源请求。
  • 正如Lionel Port所指出的,即使是单个ClassLoader也可能有多个位置来加载内容。
  • 类加载器习惯于加载类。如果程序可以将文件写入从中加载类的位置,则这很容易成为安全风险,因为用户可能会将代码注入到正在运行的应用程序中。

简短版本:不要这样做。为“我可以从中获取内容的类似资源的存储库”的概念编写一个更抽象的界面,并为“我可以从中获取内容但也可以添加内容的资源类内容的存储库”编写子接口。以一种既使用(搜索类路径)的方式实现后者,如果失败,则使用其他一些机制来获取程序可能已从某个位置添加的内容。ClassLoader.getContextClassLoader().getResource()