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

时间:2011-12-15 00:40:20

标签: java file resources copy

我有两个资源文件夹。

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文件中。

7 个答案:

答案 0 :(得分:7)

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

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

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

答案 1 :(得分:2)

Java 8解决方案

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

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

将为ProjectName/target/test-classes/newFolder。如果您正在测试用例中运行此代码。否则,它将在target/classes

不要尝试在src/resources中查找新文件夹。 肯定会在target/test-classestarget/classes中。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

如果您已加载现有文件。

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");

答案 4 :(得分:0)

剪切已编译子文件夹的主项目文件夹(“/ 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;
}
}

答案 5 :(得分:0)

以下代码与类文件一起写入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目录的想法!

答案 6 :(得分:0)

根据以下代码,您获取或创建一个文件并将其用作util方法。

public static File getFileFromResource(String filePath) {
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    return new File(Objects.requireNonNull(classloader.getResource(filePath)).getFile());
}

Project structure

您应指定文件或文件夹的相对路径。用法:

getFileFromResource("application.properties");

输出: 路径为C:\Users\????\IdeaProjects\back-end\target\classes\application.properties

的文件