如果我不首先抛出FileNotFoundExcetion,为什么file.exists()总是返回true

时间:2016-07-24 19:54:54

标签: java file-exists

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()方法将总是返回true (即使文件真的不存在)。在这种情况下,如果我不在主方法的头部抛出FileNotFoundException,则它无法将writeF写入该文件。这一定是一个愚蠢的问题,但我只是想知道这背后的机制是什么。 API也没有帮助我。我非常感谢任何可以向我解释的人。

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

2 个答案:

答案 0 :(得分:2)

您需要了解抛出此异常的位置。这个地方就是这条线:

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构造函数能够创建文件的事实,但并非总是如此。这就是你需要服务异常的原因。以下是构造函数的Java 8 API的摘录:

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的子类,并且只有一个带IOException的catch子句。但是,正如你所看到的,这里很明显它们代表两种不同的原因。

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

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

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

最后一点。其他线程的人对类似的事情感到困惑。您可以在右侧看到他们的链接。简而言之,请使用文件的完整路径。有关更多详细信息,请查看链接。

答案 1 :(得分:0)

这直接来自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();
}

这种方式如果出现问题(用户输入错误的路径/用户无权读取/写入文件),您可以处理错误而不是程序崩溃。有关try-catch块的更多信息,请检查here