簡體   English   中英

從Java的相對路徑讀取.txt文件

[英]Reading .txt File From Relative Path in Java

我知道這個問題已經問了無數種變化 ,但是今天我想強調一種特殊的情況,即當人們希望從.txt文件中讀取而不指定絕對路徑時。

假設我們在Eclipse中進行了以下設置。

projectName/packageName/subPackage/

並且在subPackage中有一個名為Read.java的類。 該類將嘗試從input1.txt讀取。

我們還input1.txt非常相同的子包內。

如果使用絕對路徑,則Read.java的代碼將是以下內容(現在假設將input1.txt放在我的桌面上是出於說明目的):

    // Create a list to store the list of strings from each line of the input1.txt.
    LinkedList<String> inputStrings = new LinkedList<String>();

    BufferedReader bufferedTextIn = null;

    try {
        String line;

        // Specify the file
        String fileName = "C:" + File.separator 
                            + "Users" + File.separator 
                            + "Kevin" + File.separator 
                            + "Desktop" +  File.separator 
                            + "input1.txt";

        bufferedTextIn = new BufferedReader(new FileReader(fileName));

        while ((line = bufferedTextIn.readLine()) != null) {
            inputStrings.add(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (bufferedTextIn != null) {
                bufferedTextIn.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

上面的問題是使用我的桌面的絕對路徑。 如果我將代碼傳遞給我的朋友,他將需要手動更改其桌面的路徑。 即使我將input1.txt放在項目文件夾中,我的朋友仍然需要手動更改路徑才能使其正常工作。

請注意,使用File.separator是一個好習慣,因為不同的OS對分隔符的解釋有些不同,但是仍然不夠。

那么我們該怎么辦呢?

這是我的解決方案。

String fileName = Read.class.getResource("input1.txt").getPath();

System.out.println(fileName);

bufferedTextIn = new BufferedReader(new FileReader(fileName));

讓我們來回顧一下場景。 我們將input1.txt文件作為Read.java放置在同一文件夾中。 因此,以上代碼嘗試轉到Read.class所在的位置(在Eclipse中bin文件夾中的某個位置),然后尋找input1.txt 這是Read.class所在位置的相對路徑(在這種情況下,它通常位於同一文件夾中,但是您可以很好地指定相對於Read.class所在的另一個文件夾)。 打印語句可讓您確切地知道它的位置,這是調試時的好習慣。

當您在Eclipse中構建時, src文件夾中的.java文件將被編譯為.class文件,並放置在bin文件夾中。 整潔的是, input1.txt可以將input1.txt復制到bin文件夾中(並保留所有程序包層次結構)。

需要注意的重要一點是使用getPath()而不是toString() ,因為后者將在路徑的前面添加一些額外的文本 (我只知道因為我將其打印出來了),因此會得到NULL pointer exception因為fileName格式不正確。

另一個需要注意的重要事情是我使用了Read.class.getResource("input1.txt").getPath(); 而不是this.getClass().getResource("input1.txt").getPath(); 因為代碼是在靜態上下文中調用的(在我的main方法中)。 如果創建對象,則可以隨意使用后者。

如果您對更高級的功能感興趣,可以查看以下鏈接:

Class.getResource()和ClassLoader.getResource()有什么區別?

我希望這有幫助!

編輯:您可以使用以下命令獲取Read.class所在的目錄。

String fileName = Read.class.getResource(".").getPath();

指定getResource("..")將轉到父目錄。

String fileName = Read.class.getResource("..").getPath();

如果您想擁有更多指定路徑的控件(例如,如果您想在Read.class所在的目錄中創建output.txt ,請使用

String fileName = Read.class.getResource(".").getPath() + "output.txt";

如果您知道文件將在運行該程序的每個系統中位於同一文件夾中,則可以使用系統變量來確保所定義的任何路徑仍可用於不同的用戶。 對於Windows,我使用了:

String user = new com.sun.security.auth.module.NTSystem().getName();

獲取用戶名。 然后可以在您的示例中將其替換為:

String fileName = "C:" + File.separator 
                        + "Users" + File.separator 
                        + user + File.separator 
                        + "Desktop" +  File.separator 
                        + "input1.txt";

我不確定這在Windows之外如何工作。

暫無
暫無

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

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