Java.io.FileNotFoundException:系统找不到指定的文件。

76

我有一个名为 "word.txt" 的文件。

它与我的 java 文件在同一目录下。

但是当我尝试在以下代码中访问它时,会出现 文件未找到 错误:

Exception in thread "main" java.io.FileNotFoundException: word.txt 
(The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(Unknown Source)
    at java.util.Scanner.<init>(Unknown Source)
    at Hangman1.main(Hangman1.java:6)

这是我的代码:

import java.io.File;
import java.util.*;

public class Hangman1 {
    public static void main(String[] args) throws Exception {
        Scanner input = new Scanner(new File("word.txt"));          
        String in = "";         
        in = input.nextLine();          
    }
}

1
请为文件指定完整路径。 - bmm6o
要么像之前说的那样使用完整路径,要么在程序中创建一个输出文件来查看它存储在哪里,然后将输入文件移动到该位置。 - Ray Stojonic
1
当您运行程序时,“word.txt”文件需要与编译器生成的.class文件位于同一目录中,而不是.java文件。在像Netbeans这样的IDE中,将文件放置在项目文件夹中,而不是源文件夹中。 - hotforfeature
8个回答

125
将word.txt文件直接放在项目根目录下作为src同级的子文件。
Project_Root
    src
    word.txt

免责声明:我想解释一下为什么这对于这种特定情况有效,而对于其他情况可能无效。

为什么有效:

当您使用 File 或任何其他 FileXxx 变量时,您是在相对于"工作目录"的文件系统上查找文件。工作目录可以描述为:

当您从命令行运行时

C:\EclipseWorkspace\ProjectRoot\bin > java com.mypackage.Hangman1

工作目录是 C:\EclipseWorkspace\ProjectRoot\bin。在您的 IDE 中(至少是我用过的所有 IDE),工作目录是 ProjectRoot。因此,当文件位于 ProjectRoot 中时,仅使用文件名作为相对路径是有效的,因为它位于工作目录的根目录中。

同样,如果这是您的项目结构 ProjectRoot\src\word.txt,那么路径 "src/word.txt" 将是有效的。

为什么可能无效

首先,工作目录可能会发生变化。例如,在上面的示例中从命令行运行代码时,工作目录是bin。因此,在这种情况下,它将失败,因为没有bin\word.txt
其次,如果将此项目导出为jar文件,并且配置文件已配置为包含在jar文件中,则它也会失败,因为路径将不再有效。
话虽如此,您需要确定该文件是否为(或仅为“资源” - 有时我会交替使用这些术语)。如果是这样,那么您将希望将文件构建到类路径中,并通过URL访问它。在这种特殊情况下,您需要做的第一件事情是确保文件被构建到类路径中。将文件放在项目根目录中,您必须配置构建以包括该文件。但是,如果将文件放在src或其下的某个目录中,则默认构建应将其放入类路径中。
你可以通过多种方式访问类路径资源。你可以利用Class类,它有一个getResourceXxx方法,你可以使用它来获取类路径资源。
例如,如果你将项目结构更改为ProjectRoot\src\resources\word.txt,你可以使用以下代码:
InputStream is = Hangman1.class.getResourceAsStream("/resources/word.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));

getResourceAsStream 返回一个 InputStream,但在幕后获得一个 URL。或者,如果需要的话,您可以获得一个 URLgetResource() 将返回一个 URL。

对于使用 Maven 的用户,目录结构类似于 src/main/resourcesresources 文件夹的内容会放置在类路径的根目录下。因此,如果您有一个文件在那里,那么您只需要使用 getResourceAsStream("/thefile.txt")


24

相对路径可以使用,但它们可能很棘手。最好的解决方案是知道你的文件正在保存的位置,也就是打印文件夹:

相对路径可用,但有时会带来麻烦。最佳解决方法是了解文件保存的目录,即打印文件夹:

import java.io.File;
import java.util.*;

public class Hangman1 {

    public static void main(String[] args) throws Exception {
        File myFile = new File("word.txt");
        System.out.println("Attempting to read from file in: "+myFile.getCanonicalPath());

        Scanner input = new Scanner(myFile);
        String in = "";
        in = input.nextLine();
    }

}

这段代码应该会打印出它正在查找的文件夹。将文件放在那里,你就可以顺利运行了。


2
但是他没有得到一个文件未找到的异常吗?如果是这种情况,File myFile = new File("word.txt"); 将会失败。 - Алексей
2
他的代码中在new Scanner(new File())处出现了异常。他应该先声明文件以进行检查。 - hotforfeature
5
只有在他尝试打开文件时,才会出现异常。new File("whatever you want");不会抛出异常。 - acdcjunior

4

您的文件应直接位于项目文件夹下,而不是任何其他子文件夹中。

如果您的项目文件夹名称为例如AProject,则它应该与您的src文件夹位于同一位置。

Aproject
        src
        word.txt

3
尝试使用代码创建文件,这样您就可以了解系统创建文件的路径。
File test=new File("check.txt");
if (test.createNewFile()) {
    System.out.println("File created: " + test.getName());
  }

2
我从属性文件中读取路径时,没有注意到末尾有一个空格。请确保您的路径末尾没有空格。

2
确保在创建txt文件时,不要输入名称“name.txt”,只需输入“name”。如果输入“name.txt”,Eclipse会将其视为“name.txt.txt”。这对于我来说解决了问题。同时将文件保存在src文件夹中,而不是java文件所在的文件夹中,向上移动一个文件夹。

1
我有同样的问题,但你知道为什么吗?因为我没有在我的文件末尾加上 .txt,所以它不是一个文本文件,你只需做两件事:
  1. 将您的文本文件放在根目录中(例如,如果您有一个名为 HelloWorld 的项目,请右键单击包目录中的 HelloWorld 文件并创建文件)
  2. 将该文件另存为任何您想要的名称,但在其末尾加上 .txt 我想你的问题已经解决了,但我写下来让其他人知道。 谢谢。

-1

我认为问题总是归结于classpath。话虽如此,如果您从与您的.class文件相同的文件夹运行,则将Scanner input = new Scanner(new File("word.txt"));更改为Scanner input = new Scanner(new File("./word.txt"));应该可以解决问题。


2
这个答案是不正确的。当前工作目录和类路径可以完全不同。 - Robin Green

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接