[英]Create file in resources/source folder in java programmatically?
我有兩個資源文件夾。
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 文件中。
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
。
正如其他人提到的,資源是通過 ClassLoader 獲取的。 然而,目前的兩種回應都沒有強調以下幾點:
java.lang.ClassLoader
可能實現的任何內容。 簡短版本:不要這樣做。 為“我可以從中獲取東西的類似資源的存儲庫”的概念編寫一個更抽象的接口,並為“我可以從中獲取和添加東西的類似資源的存儲庫”編寫子接口。 以既使用ClassLoader.getContextClassLoader().getResource()
(搜索類路徑)的方式實現后者,如果失敗,則使用其他機制來獲取程序可能從某個位置添加的內容。
剪切已編譯子文件夾(“/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
目錄的想法!
根據以下代碼,您可以獲取或創建一個文件並將其用作 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
資源通過類加載器加載,默認的類加載器緩存。
您需要自己的類加載器以及您需要的行為,以從非靜態文件系統中讀取資源。
問題是類路徑可以包含多個根目錄,因此在沒有現有文件或目錄的情況下很難區分要存儲哪個。
如果您加載了現有文件。
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");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.