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

我有两个资源文件夹。

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(); } 

在创建之前:

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

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

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

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

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

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

资源通过类加载器加载,默认的类加载器缓存。

您需要自己的类加载器以及您需要的行为,以从非静态文件系统中读取资源。

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

如果您已加载现有文件。

 File existingFile = ...; File parentDirectory = existingFile.getParentFile(); new File(parentDirectory, "newProperties.properties"); 

否则,尝试获取资源目录中唯一的目录。 (不确定这是否有效)

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

剪切已编译子文件夹的主项目文件夹(“/ target / classes”,“target / test-classes”),您可以使用以下基本路径重建项目文件夹:

 import java.io.File; import java.io.IOException; import java.net.URISyntaxException; public class SubfolderCreator { public static void main(String... args) throws URISyntaxException, IOException { File newResourceFolder = createResourceSubFolder("newFolder"); } private static File createResourceSubFolder(String folderName) throws URISyntaxException, IOException { java.net.URL url = SubfolderCreator.class.getResource("/EXISTING_SUBFOLDER/"); File fullPathToSubfolder = new File(url.toURI()).getAbsoluteFile(); String projectFolder = fullPathToSubfolder.getAbsolutePath().split("target")[0]; File testResultsFolder = new File(projectFolder + "src/test/resources/" + folderName); if (!testResultsFolder.exists()) { testResultsFolder.mkdir(); } return testResultsFolder; } } 

以下代码与类文件一起写入classes目录。

正如其他人所说,请注意覆盖类文件。 最好将新文件放入单独的目录中; 但是,该目录需要已经存在。 要创建它,请在源中的资源中创建一个子目录,可能包含一个空文件。 例如src\main\resources\dir\empty.txt

 public class WriteResource { public static void main(String[] args) throws FileNotFoundException { String thing = "Text to write to the file"; String dir = WriteResource.class.getResource("/").getFile(); //String dir = WriteResource.class.getResource("/dir").getFile(); OutputStream os = new FileOutputStream(dir + "/file.txt"); final PrintStream printStream = new PrintStream(os); printStream.println(thing); printStream.close(); } } 

这样做可以解决这个问题,但我会对在严格控制的环境之外部署这个问题感到紧张。 我真的不喜欢未经授权的人写入我的classes目录的想法!