簡體   English   中英

Java FileNotFoundException 即使文件存在

[英]Java FileNotFoundException even if the file exists

我正在構建一個應用程序,我需要將包含用戶信息的HashMap<Integer, User>存儲到文件中。 每當程序啟動時,如果users文件不存在,它將創建一個新的空文件,並且每當有新用戶注冊時,我都會調用 function saveUsers()HashMap保存到文件中。 當用戶想要登錄時,我調用 function loadUsers()讀取文件並將 object 存儲在名為usersHashMap中。 問題是,即使文件存在並且使用絕對路徑,每當我調用loadUsers()時程序總是拋出FileNotFoundException

這是我的功能:

public void saveUsers() throws IOException {
    File file = new File(usersFile);
    FileOutputStream f = new FileOutputStream(file);
    ObjectOutputStream s = new ObjectOutputStream(f);
    s.writeObject(users);
    s.close();
}

public void loadUsers() throws IOException {
    File file = new File(usersFile);
    //System.out.println(file.exists()); always returns false
    //System.out.println(file.getAbsolutePath().exists()); always returns false
    FileInputStream f = new FileInputStream(file);
    ObjectInputStream s = new ObjectInputStream(f);
    try {
        users = (HashMap<Integer, User>) s.readObject();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    s.close();
}

登錄function里面:

try {
        loadUsers();
    } catch (IOException e) {
        System.out.println(e);
        // Here I always get this :
        // java.io.FileNotFoundException: C:\Users\Me\Desktop\users.dat
        // (The filename, directory name, or volume label syntax is incorrect)
    }

Users class 是可序列化的,並且usersFile = "C:\\Users\\Me\\Desktop\\users.dat"

我嘗試在開始時使用file:///正斜杠反斜杠,但似乎沒有任何效果。

當我在命令提示符下運行dir C:\Users\Me\Desktop\users.dat時,我得到了這個:

Directory of C:\Users\Me\Desktop\users.dat

06/04/2020  01:03               616 users.dat
           1 File(s)            616 bytes
           0 Dir(s)  54,714,023,936 bytes free

異常和堆棧跟蹤:

java.io.FileNotFoundException: C:\Users\Me\Desktop\users.dat    
(The filename, directory name, or volume label syntax is incorrect)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at com.APP.loadUsers(APP.java:710)
    at com.APP.login(APP.java:722)
    at com.APP.lambda$6(APP.java:221) 

編輯:

我試過這個:

public void loadUsers() throws IOException {
    try (ObjectInputStream s = new 
    ObjectInputStream(Files.newInputStream(Paths.get(usersFile)))) {
       try {
            users = (HashMap<Integer, User>) s.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

並得到這個錯誤:

> at index 33: C:\Users\Me\Desktop\users.dat <

    at sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)    
    at sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)     
    at sun.nio.fs.WindowsPath.parse(WindowsPath.java:94)
    at sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:255)  
    at java.nio.file.Paths.get(Paths.java:84)

該錯誤強烈表明該字符串中有某種 unicode 字符。 我建議您刪除整行並手動重新輸入以避免這種情況。

或者,也許您出於提出問題的目的“清理”了該名稱,在這種情況下:您的名稱中是否有一個花哨的字符(不是 ASCII 范圍內的字符?)——那么這可能就是問題所在。

你不應該也不應該把file://放在前面; 這種代碼風格的正確方法是: File file = new File("C:\\Users\\Foo\\Bar");

舊的 Java 文件 I/O API 因生成誤導性錯誤消息而臭名昭著。 使用較新的 NIO.2 API,它是在 Java 7 中添加的。

您還應該使用 try-with-resources,也添加在 Java 7 中。除非您堅持使用古老的 Java 6 或更早版本,否則沒有不使用較新 API 的好借口。

這將使您的代碼如下所示:

public void loadUsers() throws IOException {
    try (ObjectInputStream s = new ObjectInputStream(Files.newInputStream(Paths.get(usersFile)))) {
        try {
            users = (HashMap<Integer, User>) s.readObject();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

即使這仍然失敗,它也可能會提供不同的錯誤,例如“訪問被拒絕”。

暫無
暫無

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

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