簡體   English   中英

當路徑為“./”時,我應該在哪里放置文件?

[英]Where should I place a file when the path is "./"?

我正在維護一個 Spring Boot 項目。 有這個代碼:

BufferedReader reader = new BufferedReader(new FileReader("./setting_mail_sender.txt"));

在這種情況下,文件應該放在哪里?

在“當前工作目錄”中。 那在哪里? 誰知道!

誰寫的代碼搞砸了。 將 CWD 用於任何Java 代碼中的任何內容都不是一個好主意,除非您明確知道自己需要它。 通常,只有當您使用您在普通 linux 發行版的/bin目錄中找到的各種工具編寫命令行工具時,才會出現這種情況——這種情況很少發生,因為 JVM 並不是真正為這種類型而設計的。事物。

根據數據的性質,“數據文件”有 3 種不同的最佳實踐:

  • 靜態的、不變的數據——你的應用程序的一部分和你的類文件一樣多。 這些應該與MyClass.class.getResource("name-of-resource.txt")一起加載,並以與您的類相同的方式發送。 比如jar文件里面

  • 配置文件。 這些通常應該在System.getProperty("user.home") - 用戶的主目錄; Mac 上的/Users/yourusername ,Linux 上的/home/yourusername ,Windows 上的C:\Users\YourUserName 最佳實踐是在 jar 文件中提供相關的設置文件的“模板”版本,並在檢測到根本不存在配置文件時,寫出模板(然后通過MyClass.class.getResource加載模板MyClass.class.getResource )。 如果模板不是一個好主意,類似的事情。 不好的做法是讓安裝程序執行此操作,並讓您的應用程序損壞或讓用戶不得不仔細閱讀復雜的文檔來(重新)創建配置文件。 另一種正確的方法是在您的應用程序(窗口、菜單欄設置、Web 應用程序的東西 - 帶有用戶界面的東西)中有一個配置頁面,您可以在其中更改設置,而配置文件就是您存儲它的方式數據。

  • 更改數據文件。 例如,您將 H2(一個全 Java 數據庫引擎)與您的應用程序一起提供,它需要將其數據庫文件寫入某處。 這有點棘手; 用戶主頁不是此類數據文件的正確位置,但您也無法真正“找到”安裝應用程序的目錄。 即使您可以,在設計良好的操作系統上,應用程序通常不能(也不應該!)無論如何都能夠寫入該位置。 存儲這些數據的位置絕對應該是可配置的,因此一個簡單的方法是要求用戶明確選擇一個位置。 否則我擔心你不得不編寫每個操作系統的代碼 - 在 mac 上找到/Users/myusername/Library/Application Support/yourappname ,這是正確的地方。 據我所知,沒有圖書館可以做到這一點。

它們都不涉及“要求用戶使用正確的 CWD 啟動應用程序”。 這有充分的理由:它可能很難配置,而且用戶不會想到配置。 例如,當在 windows 中將 java 應用程序設置為重復任務時,您可以為此類進程配置工作目錄,但這通常不是關鍵配置。 從命令行運行 java 應用程序時,誰知道工作目錄是什么。 您最終會得到一個通常可以運行的應用程序,除非在某些情況下它神奇地不起作用,並且您的大多數用戶不知道神奇運行和不正常運行之間的區別在於目錄他們在啟動 java 應用程序時就在里面。

如果您可以編輯該代碼,請執行此操作 - 找出這 3 種不同類型的數據中的哪一種(聽起來像第二個項目符號:配置內容,因此應該在用戶主頁中,並且應用程序的名稱應該是文件的一部分名稱) - 並修復它。 例如,應該是:

try (var in = Files.newBufferedReader(Paths.get(System.getProperty("user.home"), "myapp-mail.conf")) {

}

這解決了一大堆問題:

  • 使用 try-with 避免資源泄漏。
  • 從 user.home 讀取,避免當前工作目錄作為相關設置。
  • 實際上使用 UTF-8 編碼(而您的代碼將至少在 java 17 之前執行“平台默認值”。您不太可能希望這樣做,因為這意味着您的配置文件不可移植;將其從一台計算機復制到另一台計算機可能會中斷東西。你大概不想要這個。
  • 如果發生錯誤,則會改進錯誤消息(“舊”文件 API 的缺點之一)。

如果您無法更改此代碼,請弄清楚 CWD 是什么; 將文件放在那里,並確保無論您如何啟動此 Spring Boot 項目,始終從該目錄啟動它。 如果您無法更改此代碼但可以在該 JVM 中運行一些代碼,則可以打印它: System.out.println(Paths.get(".").toAbsolutePath())將顯示給您。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM