Java 在user.dir中找不到文件
我有一行简单的代码,可以打印出文件的第一行:Java 在user.dir中找不到文件,java,Java,我有一行简单的代码,可以打印出文件的第一行: System.out.println(new BufferedReader(new FileReader("file")).readLine()); 带有此行的类文件位于c:/users/my/project中。 名为“file”的文件存在于c:/users/my/project中。 如果我打开CMD,导航到c:/users/my/project并运行 java MyClass 第一行打印出来了,一切正常 但是如果我在CMD中导航到C://,并
System.out.println(new BufferedReader(new FileReader("file")).readLine());
带有此行的类文件位于c:/users/my/project
中。
名为“file”的文件存在于c:/users/my/project
中。
如果我打开CMD,导航到c:/users/my/project
并运行
java MyClass
第一行打印出来了,一切正常
但是如果我在CMD中导航到C://
,并运行
java -Duser.dir=c:/users/my/project MyClass
我得到一个响应,文件“file”找不到
如果我将“file”移动到c://并再次运行相同的命令,则会找到它
据我所知,更改user.dir
应该相当于我在它指向的文件夹中,但这似乎是真的。类文件位于user.dir
中,但文件仍位于我运行命令的文件夹中,而不是user.dir
指向的文件夹中
这是为什么?如果您导航到另一个目录并尝试使用不同的
user.dir运行程序,您还必须设置类路径。您得到的错误是因为找不到类,而不是因为找不到文件
试一试
关于user.dir
属性,请查看文件
类的。它说
路径名(无论是抽象的还是字符串形式的)可以是绝对的,也可以是相对的。绝对路径名是完整的,因为不需要其他信息来定位它所表示的文件。相反,相对路径名必须根据从其他路径名获取的信息进行解释。默认情况下,java.io包中的类总是根据当前用户目录解析相对路径名。此目录由系统属性user.dir
命名,通常是调用Java虚拟机的目录
编辑
我在我的机器上做了一个测试,发现文件读取器在启动应用程序的目录中查找(这可能与user.dir
属性不一致)。见下文:
public static void main(String...args) {
try {
System.out.println("abs path to test.txt : " + new java.io.File("test.txt").getAbsolutePath());
System.out.println("user home : " + System.getProperty("user.home"));
System.out.println("user.dir : " + System.getProperty("user.dir"));
System.out.println("running from : " + new java.io.File(".").getAbsolutePath());
System.out.println(new java.io.BufferedReader(new java.io.FileReader("test.txt")).readLine());
} catch (Exception e) {
System.out.println("Not found");
}
}
从一个没有文件的目录启动
C:\Users>java -Duser.home=C:\Users\william -Duser.dir=C:\Users\william -classpath C:\Users\william\Desktop Test
abs path to test.txt : C:\Users\william\test.txt
user home : C:\Users\william
user.dir : C:\Users\william
running from : C:\Users\william\.
Not found
而从一个包含我要查找的文件的目录启动它
C:\Users\william>java -Duser.home=C:\Users\william -Duser.dir=C:\Users\william -classpath C:\Users\william\Desktop Test
abs path to test.txt : C:\Users\william\test.txt
user home : C:\Users\william
user.dir : C:\Users\william
running from : C:\Users\william\.
hello world
另一次编辑
我使用的是openjdk 8,因此在我的例子中,从其来源来看,逻辑如下:
FileReader带String
arg的构造函数
public FileReader(String fileName) throws FileNotFoundException {
super(new FileInputStream(fileName));
}
FileInputStream构造函数
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}
文件输入流打开(字符串)
open0(String)
方法是本机调用(见下文)
深入挖掘FileInputStream.c中的本机调用
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_open0(JNIEnv *env, jobject this, jstring path) {
fileOpen(env, this, path, fis_fd, O_RDONLY);
}
因此,name
就是本机fileOpen
方法将使用的路径。这将转换为file.getPath()
,它不同于file.getAbsolutePath()
file.getPath()
与file
一起作为新文件(“test.txt”)
返回可能找不到的test.txt
这是我能做的最好的了,我希望它能有所帮助
看看这个和这个。简而言之,通过命令行设置user.dir是一个坏消息。您将遇到FileNotFound异常,因为程序无法找到您试图读取的文件(在您的情况下,文件名也是“file”)
问题来了,因为您只定义了文件名而没有定义路径。您应该给出它从任何目录工作的绝对或相对路径。在缺少路径定义的情况下,程序将尝试从当前目录中执行命令的文件中读取
让我们深入了解一下细节:
文本文件的路径为:c:/users/my/project/file
Java文件的路径为:c:/users/my/project/MyClass
现在,当您在c:/users/my/project目录中运行时,您将获得预期的输出,因为文本文件“file”仅在此目录中定义
当您切换到c:并尝试运行该程序时,会出现异常,因为它试图查找不存在的“c:/file”
尝试将该行改为提及绝对路径:
System.out.println(新的BufferedReader(新的文件读取器(“c:/users/my/project/file”)).readLine()您能在System.out.println之前尝试一下吗:System.out.println(“user.dir:+System.getProperty(“user.dir”);System.setProperty(“user.dir”,“c:/users/my/project”)代码>try-Duser.dir=/users/my/project@JoopEggen添加这些行后,它将打印出正确的user.dir。Output:user.dir:c:/users/my/project Exception在线程“main”java.io.FileNotFoundException:file中(系统找不到指定的文件)@BorisChistov尝试了它。类文件像以前一样被找到,但我仍然在线程“main”java.io.FileNotFoundException:file中得到了文件未找到异常:异常(系统找不到指定的文件)您使用旧文件API而不是NIO有什么具体原因吗?(文件
,路径
,路径
)我认为你是不对的。我得到的错误不是因为找不到类,而是因为在线程“main”java.io.FileNotFoundException:file中找不到文件:Exception(系统找不到指定的文件)。此外,我还添加了代码,将类路径的所有条目打印到代码的开头。当使用我的命令:java-Duser.dir=c:/users/my/project MyClass from c:/启动类时,只有类路径条目是c:/users/my/project,因此类路径似乎自动设置为user.dir。@donaldtbd有趣的问题,我做了一些测试并更新了答案,所以这似乎是FileReader的一个bug/功能?@donaldtbd我再次更新了答案,这只是预期的行为,至少在openjdk 8中是这样的,但“预期的行为”违背了文档中的规定:“默认情况下,java.io包中的类总是解决问题。”
private void open(String name) throws FileNotFoundException {
open0(name);
}
private native void open0(String name) throws FileNotFoundException;
JNIEXPORT void JNICALL
Java_java_io_FileInputStream_open0(JNIEnv *env, jobject this, jstring path) {
fileOpen(env, this, path, fis_fd, O_RDONLY);
}