我有两个资源文件夹。
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文件中。
答案 0 :(得分:7)
正如其他人所提到的,资源是通过ClassLoader获得的。然而,目前的两个回应未能强调的是这些要点:
java.lang.ClassLoader
实现的任何内容。简短版:不要这样做。为“我可以从中获取资源的资源类存储库”的概念编写一个更抽象的接口,以及“我可以从中获取资源的资源类资源的存储库”的子接口,还可以添加来自的东西。以一种使用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-classes
或target/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());
}
您应指定文件或文件夹的相对路径。用法:
getFileFromResource("application.properties");
输出:
路径为C:\Users\????\IdeaProjects\back-end\target\classes\application.properties