簡體   English   中英

Java 說 FileNotFoundException 但文件存在

[英]Java says FileNotFoundException but file exists

我為我的 CS class 分配了一個任務,它說要讀取一個包含多個測試分數的文件,並要求我對它們求和並取平均值。 雖然求和和求平均值很容易,但我在讀取文件時遇到了問題。 講師說要使用這種語法

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

有很多情況可能在運行時拋出FileNotFoundException

  1. 命名的文件不存在。 這可能有多種原因,包括:

    • 路徑名完全錯誤
    • 路徑名看起來正確但實際上是錯誤的,因為它包含您沒有注意到的非打印字符(或同形文字)
    • 路徑名是相對的,相對於正在運行的應用程序的實際當前目錄,它不能正確解析。 這通常是因為應用程序的當前目錄不是您所期望或假設的。
    • 文件路徑損壞; 例如,路徑的目錄名稱不正確,路徑上的符號鏈接已損壞,或者路徑組件之一存在權限問題。
  2. 命名文件實際上是一個目錄。

  3. 由於某種原因,無法打開命名文件進行讀取。

好消息是,問題必然是上述問題之一。 這只是一個解決問題的問題。 以下是您可以嘗試的一些方法:

  • 調用file.exists()將告訴您是否存在具有給定名稱/路徑名的任何文件系統對象。

  • 調用file.isDirectory()將測試它是否是一個目錄。

  • 調用file.canRead()將測試它是否是可讀文件。

  • 這一行會告訴你當前目錄是什么:

     System.out.println(new File(".").getAbsolutePath());
  • 這一行將以一種更容易發現意外前導或尾隨空格之類的方式打印出路徑名:

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

    在輸出中查找意外的空格、換行符等。


事實證明,您的示例代碼存在編譯錯誤。

我在沒有處理 Netbeans 的投訴的情況下運行了您的代碼,只是為了得到以下異常消息:

線程“main”中的異常 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子句中聲明它。 上述修復采用后一種方法。

代碼本身工作正常。 問題是,程序工作路徑指向的地方比你想象的要多。

使用這一行,看看路徑在哪里:

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

顯然有許多可能的原因,之前的答案很好地記錄了它們,但這是我在一個特定情況下解決這個問題的方法:

我的一個學生遇到了這個問題,我差點把頭發扯掉試圖弄清楚。 結果發現該文件不存在,即使它看起來確實存在。 問題在於 Windows 7 被配置為“隱藏已知文件類型的文件擴展名”。 這意味着如果文件似乎具有名稱“data.txt”,則其實際文件名是“data.txt.txt”。

希望這可以幫助其他人節省一些頭發。

我最近發現了一個有趣的案例,當文件明顯存在於磁盤上時,它會產生 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()); 

概括地說,不可見/非打印字符可能包含空格或制表符,也可能包含其他字符,它們可能出現在路徑的開頭、結尾或嵌入路徑中。 Trim 在某些情況下會起作用,但不是全部。 有幾件事可以幫助您發現此類問題:

  1. 輸出帶有引號字符的路徑名; 例如

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

    並仔細檢查輸出中不應該出現的空格和換行符。

  2. 使用 Java 調試器逐個字符地仔細檢查路徑名字符串,查找不應該存在的字符。 (還要檢查同形文字字符!)

一個對我有用的簡單修復方法是將我的文件從 src 移到項目的主文件夾中。 這不是最好的解決方案,但根據項目的規模和您的時間,它可能是完美的。

根據文件的權限屬性,您的操作系統可能會阻止讀取和寫入文件。

如果您嘗試從文件中讀取,那么我建議使用 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.)

除了這里提到的所有其他答案之外,您可以做一件對我有用的事情。

如果您是通過 Scanner 或命令行參數讀取路徑,請不要直接從 Windows 資源管理器中復制粘貼路徑,只需手動輸入路徑即可。

它對我有用,希望它可以幫助某人:)

我遇到了同樣的錯誤,只需添加在 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() 返回您的項目根目錄路徑,因此您必須將路徑添加到您的子目錄和包

你顯然會在一段時間后弄清楚,但只是發布這個以便它可以幫助某人。 當您的文件路徑包含任何附加或前置的空格時,也可能發生這種情況。

使用單斜杠並始終手動鍵入路徑。 例如:

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

對我有用的是捕捉異常。 沒有它,即使文件存在,編譯器也會抱怨。

InputStream file = new FileInputStream("filename");

變成

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

這對我有用。 它還可以讀取txt、csv和.in等文件

public class NewReader {

    public void read() throws FileNotFoundException, URISyntaxException {
        File file = new File(Objects.requireNonNull(NewReader.class.getResource("/test.txt")).toURI());
        Scanner sc = new Scanner(file);

        while (sc.hasNext()) {
            String text = sc.next();
            System.out.println(text);

        }
    }
}

該文件位於maven生成的資源文件夾中。如果您嵌套了其他文件夾,只需將其添加到文件名中,如“examples/test.txt”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM