如何循环执行try catch语句?

5

如何循环一个try/catch语句?我正在编写一个程序,使用Scanner从键盘读取文件。所以如果文件不存在,我希望程序会显示“文件不存在,请重试。”然后让用户键入不同的文件名。我尝试了一些不同的方法来实现这个目标,但是,所有的尝试都导致程序崩溃。

以下是我拥有的内容:

    try {
        System.out.println("Please enter the name of the file: ");
        Scanner in = new Scanner(System.in);
        File file = new File(in.next());
        Scanner scan =  new Scanner(file);
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("File does not exist please try again. ");
    }

好的,你需要实际使用 forwhile(或其他 - 在此之前请勿纠正)来循环。 - Matt Ball
5个回答

11

如果您想在失败后重试,请将该代码放入一个循环内,例如:

boolean done = false;
while (!done) {
    try {
        ...
        done = true;
    } catch (...) {
    }
}

(使用 do-while 循环会更加优雅一些。)

然而,在此情况下捕获 Exception 是一个不好的做法。它将会捕获你期望发生的异常(例如 IOException),但也会捕获未预期的异常,如 NullPointerException 等,这些是程序中存在 bug 的症状。

最佳实践是仅捕获你期望且能够处理的异常,允许其他异常传播。在你的特定情况下,捕获 FileNotFoundException 就足够了(这是 Scanner(File) 构造函数声明的)。如果你没有使用 Scanner 进行输入,你可能需要捕获 IOException


我必须纠正一个高票答案中的严重错误。

do {
    ....
} while (!file.exists());

这是错误的,因为仅测试文件是否存在是不够的:

  • 文件可能存在,但用户没有读取权限
  • 文件可能存在,但是它是一个目录
  • 由于硬盘错误或类似问题,文件可能存在但无法打开
  • exists()检测成功和随后尝试打开它之间,文件可能已被删除/取消链接/重命名

请注意:

  1. File.exists()仅测试具有指定路径的文件系统对象是否存在,并不意味着它实际上是一个文件,或者用户对它有读或写访问权限。
  2. 无法测试I/O操作是否由于硬盘错误、网络驱动器错误等而失败。
  3. 不存在打开与删除/取消链接/重命名之间的竞争条件的解决方案。虽然在正常使用中很少发生此类错误,但如果涉及安全关键文件,则此类漏洞会受到攻击。

正确的做法是简单地尝试打开文件,并在发生IOException时捕获和处理它。这更简单、更可靠,而且可能更快。对于那些认为异常不应用于"正常流程控制"的人来说,这不是正常流程控制...


7

不要使用try catch语句块,尝试使用一个do while循环检查文件是否存在。

do {

} while ( !file.exists() );

这个方法在java.io.File中。


使用 file.exists() 得分加一。另外,最好将第二个 Scanner 语句放在此循环之外。 - Sujay
感谢所有积极的评论,欢迎提出修改意见,以便用户正确使用此内容。 - squiguy
1
-1- 使用 file.exists() 是错误的。你只测试了可能失败的原因之一,而实际上有很多其他原因。此外,你无法测试所有可能性,所以即使尝试也是不好的想法。正确的方法是尝试打开文件并捕获异常。 - Stephen C
@StephenC,您在自己的答案中提到捕获“Exception”是一种不好的做法。那么,除了检查“file.exists()”之外,OP应该捕获哪些特定的异常呢?除了“FileNotFoundException”之外,我认为使用“file.exists”已经足够缓解了。 - Adam
我试图为他讲得简单些,因为他最初说他只是在学习Java。 - squiguy
@squiguy - 1)我的评论并没有说他需要处理“Exception”。它说的是异常。具体来说,他需要处理“IOException”。编译器会告诉他这一点。2)你不能通过建议一个不正确的解决方案来简化人们的生活。而且我必须说,你的解决方案是不正确的,原因在我的答案中已经列出。(首先,除非你捕获或声明已检查的异常,否则它将无法编译。) - Stephen C

1

您可以简单地将其包装在循环中:

while(...){

    try{

    } catch(Exception e) {

    }

}

然而,捕获每个异常并假设它是由于文件不存在可能不是最好的处理方式。


1

尝试类似这样的东西:

<b>boolean success = false;

while (!success)
{</b>
    try {
        System.out.println("Please enter the name of the file: ");
        Scanner in = new Scanner(System.in);
        File file = new File(in.next());
        Scanner scan =  new Scanner(file);
        <b>success = true;</b>
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.out.println("File does not exist please try again. ");
    }
<b>}</b>

这个解决方案存在许多问题。 - Stephen C

0

使用API检查文件是否存在。

String filename = "";

while(!(new File(filename)).exists())
{
    if(!filename.equals("")) System.out.println("This file does not exist.");
    System.out.println("Please enter the name of the file: ");
    Scanner in = new Scanner(System.in);
    filename = new String(in.next();        
}
File file = new File(filename);
Scanner scan =  new Scanner(file);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接