如果我一开始不抛出 FileNotFoundException,为什么 file.exists() 总是 return true

Why does file.exists() always return true if I don't throw FileNotFoundExcetion in the first place

public class Main {

final private static int MAX_RECORD_NUMBER = 20;
final private static int RECORD_LENGTH = 71;

public static void main(String[] args) throws IOException, FileNotFoundException{
    Scanner input = new Scanner(System.in);
    System.out.println("Please input the file location and name.");
    String filepath = input.next();
    File file = new File(filepath); 

    boolean isExisted = file.exists(); // Problem exists here if I delete FileNotFoundException

    RandomAccessFile store = new RandomAccessFile(file, "rw");

    if (!isExisted) {
        String dummy = "Empty record                                                           ";
        for (int i = 0; i < MAX_RECORD_NUMBER; i++) {
            store.writeUTF(dummy);
        }
    }

我在这里遇到了一个小故障。如果我没有抛出 FileNotFoundException,file.exists() 方法将 always return true(即使文件真的不存在)。在这种情况下,如果我不在 main 方法的开头抛出 FileNotFoundException,它就无法将 UTF 写入该文件。这一定是一个愚蠢的问题,但我只想知道这背后的机制是什么。 API 对我也没有帮助。我真的很感谢任何能向我解释的人。

编辑:抱歉,我之前不清楚。我真正想问的是,为什么 .exists() 方法总是 returns true 而不是 false 或其他意外错误?

这直接来自 Java API:

java.io.FileNotFoundException

This exception will be thrown by [...] when a file with the specified pathname does not exist. 

所以你可以包围

RandomAccessFile store = new RandomAccessFile(file, "rw");

像这样的 try-catch 块:

Scanner input = new Scanner(System.in);
System.out.println("Please input the file location and name.");
String filepath = input.next();
File file = new File(filepath); 
boolean isExisted = file.exists(); 

try{

    RandomAccessFile store = new RandomAccessFile(file, "rw");

    if (!isExisted) {
        String dummy = "Empty record                                                           ";
        for (int i = 0; i < MAX_RECORD_NUMBER; i++) {
            store.writeUTF(dummy);
        }
    }
}catch (FileNotFoundException e){
    System.err.println("File not found!");
    e.printStackTrace();
}catch (IOException e){
    System.err.println("Couldn't write to/read file!");
    e.printStackTrace();
}

这样如果出现问题(用户输入错误 path/the 用户无权 read/write 到文件)你可以处理错误而不是你的程序崩溃。有关 try-catch 块的更多信息,请查看 here.

你需要知道这个异常是在哪里抛出的。地点是这一行:

RandomAccessFile store = new RandomAccessFile(file, "rw");

看看 FileNotFoundException 的 API,您就会知道它在 RandomAccessFile 构造函数中按预期抛出。

在没有 RandomAccessFile 的情况下使用以下代码测试您的逻辑:

import java.io.*;
import java.util.Scanner;

public class Main {

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        System.out.println("Please input the file location and name.");
        String filepath = input.next();
        File file = new File(filepath); 
        if (file.exists()) System.out.println("EXISTS!"); else System.out.println("DOESN'T EXIST!");
    }

}

现在问题的第一部分应该清楚了。函数 file.exists() 工作正常。逻辑上的缺陷来自这样一个事实,即 RandomAccessFile 构造函数能够创建文件,但并非总是如此。这就是为什么您需要为异常提供服务。以下摘自Java8API的构造函数:

FileNotFoundException - 如果模式是 "r" 但给定的文件对象不表示现有的常规文件,或者如果模式以 "rw" 开头但给定的文件对象不表示现有的可写常规文件并且无法创建同名的新常规文件,或者如果在打开或创建文件时出现其他错误

因此您的代码的另一部分可能如下所示:

try {
    RandomAccessFile store = new RandomAccessFile(file, "rw");
    String dummy = "Empty record                                                           ";
    for (int i = 0; i < MAX_RECORD_NUMBER; i++) {
       store.writeUTF(dummy);
    }
} catch (FileNotFoundException e){
    System.err.println("File cannot be created!");
}

但这还不够,关于异常服务,因为您在这里使用了 writeUTF(dummy) 函数。这个函数抛出:

IOException - 如果发生 I/O 错误。(如 RandomAccessFile 的 API 所说。)

因此,您需要处理 IOException。例如,将一个 catch 子句附加到现有的子句,这个:

catch (IOException e){
    System.err.println("Couldn't write to file!");
} 

或者您可以跳过 FileNotFoundException,因为它是 IOException 的子class,并且只有一个带有 IOException 的 catch 子句。但是,如您所见,很明显它们代表两个不同的原因。

所以最终你的 class 看起来像这样:

import java.io.*;
import java.util.Scanner;

public class Main {

final private static int MAX_RECORD_NUMBER = 20;
final private static int RECORD_LENGTH = 71;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        System.out.println("Please input the file location and name.");
        String filepath = input.next();
        File file = new File(filepath); 
        //if (file.exists()) System.out.println("EXISTS!"); else System.out.println("DOESN'T EXIST!");

        try {
            RandomAccessFile store = new RandomAccessFile(file, "rw");
            String dummy = "Empty record                                                           ";
            for (int i = 0; i < MAX_RECORD_NUMBER; i++) {
               store.writeUTF(dummy);
            }
        } catch (FileNotFoundException e){
            System.err.println("File cannot be created!");
        } catch (IOException e){
            System.err.println("Couldn't write to file!");
        }
    }
}

有些部分不需要。分析我的解决方案,它应该澄清你的错误。或者问我更多。无论如何,这个答案有点冗长。

最后一点。其他线程中的人对类似的事情感到困惑。您可以在右侧看到它们的链接。长话短说,使用文件的完整路径。有关详细信息,请查看链接。