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