【问题标题】:How to loop a try catch statement?如何循环一个try catch语句?
【发布时间】:2012-08-27 08:13:22
【问题描述】:

如何循环 try/catch 语句?我正在制作一个使用扫描仪读取文件的程序,它正在从键盘读取它。所以我想要的是如果文件不存在,程序会说“这个文件不存在,请重试。”然后让用户输入不同的文件名。我尝试了几种不同的方法来尝试这样做,但是我所有的尝试都以程序崩溃告终。

这就是我所拥有的

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

【问题讨论】:

  • 嗯,你需要实际使用 for 或 while(或其他 - 在学究之前 ;-) 才能循环。

标签: java loops try-catch


【解决方案1】:

试试这样的:

boolean success = false;

while (!success)
{
    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);
        success = true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        System.out.println("File does not exist please try again. ");
    }
}

【讨论】:

  • 这个解决方案有很多问题。
【解决方案2】:

如果您想在失败后重试,则需要将该代码放入循环中;例如像这样:

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

(do-while 是一个稍微优雅的解决方案。)

但是,在这种情况下捕获 Exception 是不好的做法。它不仅会捕获您期望发生的异常(例如IOException),还会捕获意外的异常,例如NullPointerException 等等,这些都是您的程序中的错误症状。

最佳做法是捕获您期望(并且可以处理)的异常,并允许任何其他异常传播。在您的特定情况下,捕获 FileNotFoundException 就足够了。 (这就是 Scanner(File) 构造函数声明的内容。)如果您没有使用 Scanner 作为输入,则可能需要捕获 IOException。


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

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

这是不正确的,因为测试文件是否存在是不够的:

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

注意:

  1. File.exists() 仅测试文件系统对象是否以指定路径存在,而不是它实际上是一个文件,或者用户对其具有读取或写入权限。
  2. 无法测试 I/O 操作是否将由于硬盘错误、网络驱动器错误等而失败。
  3. 没有解决打开与删除/未链接/重命名竞争条件的方法。虽然在正常使用中很少见,但如果有问题的文件对安全性至关重要,这种错误可以作为目标。

正确的方法是简单地尝试打开文件,如果发生这种情况,捕获并处理IOException。它更简单、更健壮,而且可能更快。而对于那些会说不应将异常用于“正常流量控制”的人,这不是正常的流量控制......

【讨论】:

    【解决方案3】:

    使用 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);
    

    【讨论】:

      【解决方案4】:

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

      while(...){
      
          try{
      
          } catch(Exception e) {
      
          }
      
      }
      

      但是,捕获每个异常并假设它是由于文件不存在可能不是解决此问题的最佳方法。

      【讨论】:

        【解决方案5】:

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

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

        这个方法在java.io.File

        【讨论】:

        • +1 用于使用file.exists()。补充一点,最好将第二个 Scanner 语句放在这个循环之外。
        • 感谢所有积极的 cmets,请随时提出修改建议,以便用户正确使用。
        • -1 - 用于使用file.exists()。您仅出于多种原因之一进行了测试,而提供的文件可能无法打开。此外,您无法测试所有可能性,因此即使尝试也是个坏主意。这确实是错误的做法。正确的方法是尝试打开文件并捕获异常。
        • @StephenC 您在自己的回答中表示,捕获Exception 是一种不好的做法。那么,具体来说,OP 应该捕获哪些异常而不是检查file.exists()?除了FileNotFoundException,我认为使用file.exists 可以充分缓解。
        • 我试图让他保持简单,因为他最初说他只是在学习 Java。
        猜你喜欢
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多