Java FileNotFoundException, даже если файл существует - PullRequest
0 голосов
/ 06 апреля 2020

Я создаю приложение, в котором мне нужно сохранить HashMap<Integer, User>, содержащий информацию о пользователях, в файл. Всякий раз, когда программа запускается, если файл users не существует, он создает новый пустой файл, и всякий раз, когда регистрируется новый пользователь, я вызываю функцию saveUsers(), которая сохраняет HashMap в файл. Когда пользователь хочет войти, я вызываю функцию loadUsers(), которая читает файл и сохраняет объект в HashMap с именем users. Проблема в том, что программа всегда выдает 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)

Ответы [ 2 ]

4 голосов
/ 06 апреля 2020

Ошибка указывает на то, что в этой строке есть какой-то символ Юникода. Я предлагаю вам удалить всю строку и набрать ее вручную, чтобы избежать этого.

В качестве альтернативы, возможно, вы «очистили» это имя для того, чтобы задать вопрос, и в этом случае: существует ли причудливый символ на ваше имя (что-то не из диапазона ASCII?) - тогда, вероятно, проблема.

Вы не должны и не должны ставить file:// перед этим; правильный способ для этого стиля кода: File file = new File("C:\\Users\\Foo\\Bar");

1 голос
/ 06 апреля 2020

Старый Java File I / O API печально известен тем, что генерирует вводящие в заблуждение сообщения об ошибках. Используйте более новый API NIO.2, который был добавлен в 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();
        }
    }
}

Даже если это все равно не помогло, это могло бы обеспечить другая ошибка, например, «доступ запрещен».

...