Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在user.dir中找不到文件_Java - Fatal编程技术网

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);
}