从Java中的相对路径读取.text文件

时间:2014-03-11 14:06:27

标签: java eclipse

我知道这个问题已经在无数的变种中被问到了,但今天我想强调一个特殊的情况,当一个人希望从.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是一种很好的做法,因为不同的操作系统对分隔符的解释略有不同,但仍然不够。

那么我们该做什么呢?

2 个答案:

答案 0 :(得分:2)

这是我的解决方案。

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所在位置的另一个文件夹)。 print语句可以让您确切地知道它的位置,并且在调试时是一个很好的做法。

在Eclipse中构建时, src 文件夹中的.java文件将被编译为.class个文件,并放在 bin 中夹。巧妙的是,input1.txt也被复制到 bin 文件夹上(并且维护了所有包层次结构)。

需要注意的一件重要事情是使用getPath()而不是toString(),因为后者会在路径前面添加一些额外文本(我只知道因为我把它打印出来了,因此你得到了NULL pointer exception因为fileName格式不正确。

另一个需要注意的重要事项是我使用Read.class.getResource("input1.txt").getPath();而不是this.getClass().getResource("input1.txt").getPath();,因为代码是在静态上下文中调用的(在我的main方法中)。如果你创建了一个对象,那么可以随意使用后者。

如果您对更高级的功能感兴趣,可以查看以下链接:

What is the difference between Class.getResource() and 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";

答案 1 :(得分:1)

如果您知道该文件将位于运行此程序的每个系统中的同一文件夹中,则可以使用系统变量来确保定义的任何路径仍可用于不同的用户。对于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之外是如何工作的。