即使文件存在,Java FileNotFoundException

问题描述 投票:-1回答:2

我正在构建一个应用程序,需要在其中将包含用户信息的HashMap<Integer, User>存储到文件中。每当程序启动时,如果users文件不存在,它将创建一个新的空文件,并且每当有新用户注册时,我都会调用函数saveUsers(),该函数会将HashMap保存到文件中。当用户想要登录时,我调用函数loadUsers()来读取文件并将对象存储在名为HashMapusers中。问题在于,即使文件存在并使用绝对路径,只要我调用FileNotFoundException,程序总是会抛出loadUsers()

这是我的职能:

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

在登录功能内:

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类是可序列化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)
java filenotfoundexception
2个回答
2
投票

该错误强烈表明该字符串中存在某种Unicode字符。我建议您删除整行,然后手动键入以免出现这种情况。

或者,您可能是出于询问的目的而“清理”了该名称,在这种情况下:您的名称中是否有一个奇特的字符(不是ASCII范围内的字符?),这可能就是问题所在。

您不也不应在此前面加上file://;这种代码风格的正确方法是:File file = new File("C:\\Users\\Foo\\Bar");


1
投票

旧的Java File I / O API众所周知会产生误导性的错误消息。使用Java 7中添加的更新的NIO.2 API。

您还应该使用在Java 7中也添加的try-with-resources。除非您使用的是古老的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();
        }
    }
}

即使仍然失败,它也可能会提供其他错误,例如“访问被拒绝”。

© www.soinside.com 2019 - 2024. All rights reserved.