【问题标题】:Java says FileNotFoundException but file existsJava 说 FileNotFoundException 但文件存在
【发布时间】:2013-10-18 21:54:40
【问题描述】:

我有一个 CS 课的作业,它说要读取一个包含多个测试分数的文件,并要求我对它们求和并取平均值。虽然求和和平均很容易,但我在读取文件时遇到了问题。老师说要用这个语法

Scanner scores = new Scanner(new File("scores.dat"));

但是,这会引发FileNotFoundException,但我一遍又一遍地检查该文件是否存在于当前文件夹中,然后,我认为它必须对权限做一些事情。我为每个人更改了读写权限,但它仍然不起作用,它仍然不断抛出错误。有谁知道为什么会发生这种情况?

编辑:它实际上指向一个目录,但是,我已经解决了这个问题。现在file.exists() 返回true,但是当我尝试将它放入Scanner 时,它会抛出FileNotFoundException

这是我所有的代码

import java.util.Scanner;
import java.io.*;
public class readInt{
        public static void main(String args[]){
                File file = new File("lines.txt");
                System.out.println(file.exists());
                Scanner scan = new Scanner(file);
        }
}

【问题讨论】:

  • 什么是当前目录?尝试打印new File(".")
  • 打印new File("scores.dat")的路径,并仔细检查它是否存在于预期的目录中。
  • @Steinar 它正在正确的目录中搜索,并且给出了正确的绝对路径,但是仍然找不到该文件
  • 异常的文本是什么?
  • 几乎可以肯定您进入了错误的目录。打印new File("scores.dat").getAbsolutePath() 并确保文件确实在那个位置。

标签: java filenotfoundexception


【解决方案1】:

在某些情况下,FileNotFoundException 可能会在运行时抛出。

  1. 指定的文件不存在。这可能有多种原因,包括:

    • 路径名完全错误
    • 路径名看起来正确但实际上是错误的,因为它包含您没有注意到的非打印字符(或同形字)
    • 路径名是相对的,相对于正在运行的应用程序的实际当前目录不能正确解析。这通常是因为应用程序的当前目录不是您所期望或假设的。
    • 文件路径损坏;例如路径的目录名称不正确,路径上的符号链接损坏,或者路径组件之一存在权限问题。
  2. 命名文件实际上是一个目录。

  3. 由于某种原因,无法打开命名文件进行读取。

好消息是,问题将不可避免地是上述问题之一。这只是解决哪个问题。以下是您可以尝试的一些方法:

  • 调用file.exists() 将告诉您是否存在任何具有给定名称/路径名的文件系统对象。

  • 调用file.isDirectory()会测试它是否是一个目录。

  • 调用file.canRead() 将测试它是否是可读文件。

  • 这一行会告诉你当前目录是什么:

      System.out.println(new File(".").getAbsolutePath());
    
  • 此行将打印出路径名,以便更容易发现意外的前导或尾随空格等内容:

      System.out.println("The path is '" + path + "'");
    

    在输出中寻找意外的空格、换行符等。


原来你的示例代码有编译错误。

我运行了您的代码,没有处理来自 Netbeans 的投诉,只是得到以下异常消息:

线程“主”java.lang.RuntimeException 中的异常:无法编译 源代码 - 未报告的异常 java.io.FileNotFoundException;必须 被抓住或被宣布被扔掉

如果您将代码更改为以下内容,它将解决那个问题。

public static void main(String[] args) throws FileNotFoundException {    
    File file = new File("scores.dat");
    System.out.println(file.exists());
    Scanner scan = new Scanner(file);
}

解释Scanner(File) 构造函数被声明为抛出FileNotFoundException 异常。 (它发生在扫描仪无法打开文件的情况。)现在FileNotFoundException 是一个已检查异常。这意味着可能抛出异常的方法必须捕获异常或在throws子句中声明它。上述修复采用后一种方法。

【讨论】:

  • 你的第三种情况包括了另外两种情况,还包括了一些其他容易区分的情况,比如权限问题、网络故障等,不是很有启发性,也没有任何意义有“三个案例”的一种情况。测试File.canRead() 在你已经必须捕获异常时是徒劳的,而当系统在打开期间无论如何都必须对其进行测试时是浪费的。
  • “如果上面的测试返回 true” - 如果返回 false 怎么办? :)
【解决方案2】:

代码本身工作正常。问题是,程序工作路径指向的地方不是你想象的。

使用这一行,看看路径在哪里:

System.out.println(new File(".").getAbsoluteFile());

【讨论】:

    【解决方案3】:

    显然有许多可能的原因,之前的答案很好地记录了它们,但这是我在一个特定情况下解决这个问题的方法:

    我的一个学生遇到了这个问题,我差点把头发扯下来试图解决这个问题。事实证明该文件不存在,即使它看起来确实存在。问题在于 Windows 7 被配置为“隐藏已知文件类型的文件扩展名”。这意味着如果文件的名称为“data.txt”,则其实际文件名为“data.txt.txt”。

    希望这可以帮助其他人节省一些头发。

    【讨论】:

      【解决方案4】:

      我最近发现了一个有趣的案例,当文件明显存在于磁盘上时会产生 FileNotFoundExeption。 在我的程序中,我从另一个文本文件中读取文件路径并创建 File 对象:

      //String path was read from file
      System.out.println(path); //file with exactly same visible path exists on disk
      File file = new File(path); 
      System.out.println(file.exists());  //false
      System.out.println(file.canRead());  //false
      FileInputStream fis = new FileInputStream(file);  // FileNotFoundExeption 
      

      问题的原因是路径末尾包含不可见的\r\n 字符。

      我的解决方法是:

      File file = new File(path.trim()); 
      

      概括地说,不可见/非打印字符可能包含空格或制表符,可能还有其他字符,它们可能出现在路径的开头、结尾或嵌入路径中。修剪在某些情况下会起作用,但不是全部。有几件事可以帮助您发现此类问题:

      1. 输出带有引号的路径名;例如

          System.out.println("Check me! '" + path + "'");
        

        并仔细检查输出中不应出现的空格和换行符。

      2. 使用 Java 调试器逐个字符地仔细检查路径名字符串,寻找不应该存在的字符。 (还要检查同形字符!)

      【讨论】:

        【解决方案5】:

        一个对我有用的简单解决方法是将我的文件从 src 移出并移到项目的主文件夹中。这不是最好的解决方案,但根据项目的规模和您的时间,它可能是完美的。

        【讨论】:

          【解决方案6】:

          根据文件的权限属性,您的操作系统可能会阻止读取和写入文件。

          如果您尝试从文件中读取,那么我建议使用 File 的 setReadable 方法将其设置为 true,或者,例如以下代码:

          String arbitrary_path = "C:/Users/Username/Blah.txt";
          byte[] data_of_file;
          File f = new File(arbitrary_path);
          f.setReadable(true);
          data_of_file = Files.readAllBytes(f);
          f.setReadable(false); // do this if you want to prevent un-knowledgeable 
                                //programmers from accessing your file.
          

          如果您尝试写入文件,那么我建议使用 File 的 setWritable 方法将其设置为 true,或者,例如以下代码:

          String arbitrary_path = "C:/Users/Username/Blah.txt";
          byte[] data_of_file = { (byte) 0x00, (byte) 0xFF, (byte) 0xEE };
          File f = new File(arbitrary_path);
          f.setWritable(true);
          Files.write(f, byte_array);
          f.setWritable(false); // do this if you want to prevent un-knowledgeable 
                                //programmers from changing your file (for security.)
          

          【讨论】:

            【解决方案7】:

            除了这里提到的所有其他答案,你可以做一件事对我有用。

            如果您通过扫描仪或命令行参数读取路径,而不是直接从 Windows 资源管理器复制粘贴路径,只需手动输入路径。

            它对我有用,希望它可以帮助某人:)

            【讨论】:

              【解决方案8】:

              我遇到了同样的错误,只需添加在 Java 项目结构中找到的 src 目录即可解决。

              String path = System.getProperty("user.dir") + "\\src\\package_name\\file_name";
              File file = new File(path);
              Scanner scanner = new Scanner(file);
              

              请注意 System.getProperty("user.dir") 和 new File(".").getAbsolutePath() 返回您的项目根目录路径,因此您必须将路径添加到您的子目录和包

              【讨论】:

              • 虽然这对您有用,但这种方法存在问题。 1) 您通过使用特定于 Windows 的路径名语法使您的应用程序平台依赖。 2)您假设您的代码将在当前目录设置为构建目录(或其他内容)的情况下执行。当您将代码发送给其他人时,这将不起作用。
              • 如果您尝试读取的文件是源代码库的一部分,最好将其复制到您的 JAR 文件(或包含已编译类的文件树)中并使用 getResourceAsStream通过(运行时)类路径找到它。
              【解决方案9】:

              您显然会在一段时间后弄清楚,但只是发布此内容以便它可能对某人有所帮助。当您的文件路径包含附加或前置的任何空格时,也会发生这种情况。

              【讨论】:

                【解决方案10】:

                使用单个正斜杠并始终手动键入路径。例如:

                FileInputStream fi= new FileInputStream("D:/excelfiles/myxcel.xlsx");
                

                【讨论】:

                  【解决方案11】:

                  对我有用的是捕捉异常。没有它,即使文件存在,编译器也会报错。

                  InputStream file = new FileInputStream("filename");
                  

                  改为

                  try{
                      InputStream file = new FileInputStream("filename");
                      System.out.println(file.available());
                  }
                  catch (Exception e){
                      System.out.println(e);
                  }
                  

                  【讨论】:

                    猜你喜欢
                    相关资源
                    最近更新 更多