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

val*_*674 14 java resources copy file

我有两个资源文件夹.

src - 这是我的.java文件

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

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

我试过这样的事情:

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

在创建之前:

new File("/folderInResources/newProperties.properties");
Run Code Online (Sandbox Code Playgroud)

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

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

小智 8

Java 8 解决方案

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

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

这将是ProjectName/target/test-classes/newFolder. 如果您在测试用例中运行此代码。否则它会在target/classes

不要试图在你的src/resources. 它肯定会在target/test-classes或 中target/classes

  • 那么如果我想在 `src/main/resources` 目录而不是 `/target/...` 中创建文件或文件夹,该怎么办? (8认同)

Lui*_*las 7

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

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

简短版:不要这样做.为"我可以从中获取资源的资源类存储库"的概念编写一个更抽象的接口,以及"我可以从中获取资源的资源类资源的存储库"的子接口,还可以添加来自的东西.以两种方式ClassLoader.getContextClassLoader().getResource()(搜索类路径)以及如果失败的方式实现后者,使用其他一些机制来获取程序可能从某个位置添加的内容.


Lio*_*ort 1

问题是类路径可以包含多个根目录,因此在没有现有文件或目录的情况下很难区分要存储哪个根目录。

如果您已加载现有文件。

File existingFile = ...;
File parentDirectory = existingFile.getParentFile();
new File(parentDirectory, "newProperties.properties");
Run Code Online (Sandbox Code Playgroud)

否则,请尝试获取您知道在资源目录中唯一的目录的句柄。(不确定这是否有效)

URL url = this.getClass().getResource("/parentDirectory");
File parentDirectory = new File(new URI(url.toString()));
new File(parentDirectory, "newProperties.properties");
Run Code Online (Sandbox Code Playgroud)