【问题标题】:Java: How to continue reading a file after an exception is thrownJava:抛出异常后如何继续读取文件
【发布时间】:2011-12-13 14:03:32
【问题描述】:

所以我的教授给我们分配了一个项目,我们必须从文本文件中接收命令并使用它们来驱动程序的流程。这些命令(例如起飞、着陆、装载货物、卸载货物等)旨在模拟类似飞机的物体。

有时执行这些命令没有意义,例如在飞机飞行时装载货物。因此,为了防止类似的事情发生,我们必须在我们自己的异常类中编写代码,即“如果飞机在飞行中被命令装载货物,则抛出 InvalidActionException”

我的问题是:抛出异常后,我如何继续从文本文件中读入命令(看看一旦抛出异常,程序就无法继续前进了

这是我想做的事情的大纲:

    Scanner input = new Scanner(new FileInputStream("stuff1.txt"));

    while(input.hasNextLine())
    {
        try 
        {
             //execute commands by reading them using input.nextLine()
        }
        catch()
        {
            //catch any exceptions and ignore them... continue to read
           //the file for more commands
        }
    }

如果有任何帮助,我将不胜感激。谢谢。

【问题讨论】:

  • 如果你捕捉到异常,那么程序不会突然结束。确保在 catch 语句中指定正确的异常类。
  • 只需将要捕获的异常放在catch子句后面的括号之间,您就有了解决方案:catch (InvalidCommandException e) { // ignore }
  • 当你知道它是垃圾文件时,你真的要继续处理它吗??

标签: java io


【解决方案1】:

Catch 适当的异常和流程将自动达到while 循环条件。

在捕获异常后,无需执行任何额外操作即可继续程序。

【讨论】:

    【解决方案2】:

    看看一旦它们被抛出,程序如何突然结束

    只有未捕获的异常才会停止线程。我建议你捕获所有你想在之后继续的异常,你不会有问题。

    【讨论】:

      【解决方案3】:

      捕捉您的特定异常:

      while(input.hasNextLine())
      {
          try 
          {
               //execute commands by reading them using input.nextLine()
          }
          catch ( UserDefinedException ex )
          {
               //catch the exceptions you're throwing
          }
      }
      

      【讨论】:

      • 最好不要按照@Graham Borland 的建议在循环中进行。
      • @Mudassir 但这就是操作员想要的,让循环继续。格雷厄姆没有暗示,他只是陈述发生了什么。
      • @Mudassir:它必须在里面,因为 OP 想要在异常发生后读取下一行。
      • @Luchian Grigore:对不起,我的错。
      【解决方案4】:

      这正是您想要做的。所有的读取和处理语句都放在try 块中,而catch 块只包含错误处理(可能只包含在某处打印警告消息。

      您需要注意的是不要陷入死循环。确保每次循环都在处理新数据!

      【讨论】:

        【解决方案5】:

        由于您的catchwhile 循环内,因此在捕获异常后循环自然会继续进行下一次迭代。

        【讨论】:

          【解决方案6】:

          在您的 catch 块中捕获的任何异常都不会导致程序终止。只需捕获您想要处理的异常,您的循环就会继续。

          while(input.hasNextLine())
              try {
                  //execute commands by reading them using input.nextLine()
              }
              catch (CargoLoadingException e)
              {
                  System.err.println("Can't load cargo while the plane is in flight.");
              }
              catch (OtherException e)
              {
                   e.printStackTrace();
              }
          }
          

          注意,如果你捕捉到Throwable,你基本上捕捉到了任何可以抛出的异常。但是,您可能只想捕获特定的异常。例如,PlaneCrashException 可能会导致程序终止。

          【讨论】:

            【解决方案7】:

            您显示的大纲足以实现您想要的(即 try-catch-construct 在 while 循环内)。只需确保 catch 语句声明了您想要捕获并忽略的正确类型或超类型。

            更新:如果您不确定要捕获哪种异常,您可能想要捕获“Throwable”,但实际上并不推荐这样做。当您的老师让您实现自己的异常时,您可能基于一个现有的异常类。然后你可能想捕捉那个异常类型。

            另外,您可能希望在执行序列之前将文本文件中的全部命令读入字符串列表。这可能会使您避免一些 IO 问题,因为您始终保持文件句柄打开(对于这样一个简单的任务来说这似乎没有必要)。

            【讨论】:

            • 通过让文件保持打开状态,程序可以处理来自套接字或其他实时输入以及磁盘文件的数据。给定文件数据,这可能是教授希望程序编写的方式。我同意通常最好尽快关闭文件——获取数据然后处理它。
            【解决方案8】:

            补充其他答案:异常可以做很多工作。他们通常会告诉您,您的程序非常不稳定,应该立即关闭。

            通常,他们会告诉您发生了一些不好的和意外的事情,并让您有机会向用户解释问题,然后继续。例如,意外的文件结束异常。你可以告诉用户文件是坏的,让他们再试一个。您还可以打印出堆栈跟踪,以便他们可以给您打电话,即使您没有打印大量错误消息,您也可以弄清楚发生了什么。

            注意这个例外的人格分裂。与第一种类型(通常是 RunTimeException 实例)一样,它们几乎无需您做任何事情就可以让您确切地知道发生了什么。然而,Java 也迫使您意识到可能会抛出 IOException ,并试图强制您为用户编写一条好消息。对此我一直有些疑惑。如果我捕获到 EOFException,我知道它发生在哪里,并且我不需要堆栈跟踪。 (当然,如果我知道 EOF 不能 发生,我就不会费心向用户发送正确的消息,并且当它发生时的堆栈跟踪将非常方便。)

            但还有第三种例外,即前一个例外的第二人格。它只是让你知道发生了一些完全正常的事情。它非常高效(如果设置正确;见下文)。而且它比在方法调用堆栈中返回值要干净得多。它允许一个已经返回的方法,比如说,一个字符串(带有一个空引用完全可以)来提醒调用方法注意一个特殊的条件,并且可以选择在那个条件下提供大量的数据。

            public static class MyEOFException extends EOFException  {
                // Saves creating a meaningless stack trace.
                public Throwable fillInStackTrace()  { return this; }
            }
            // Saves creating a new object every time you use it
            public static MyEOFException  myEOF = new MyEOFException();
            

            然后,在方法内部:

            try  {
                for (;;)  {
                    String  text = readAStringFromFile( in );
                    //  Do something with text...
                }
            }
            catch (MyEOFException e)  {
                // Nothing at all needs to be done here.
                // Note that MyEOFException COULD have beeen set up with tons of data and
                // then a lot of work could be done.  (The file might end with binary
                // data, for instance, which would be in "e".)
            }
            

            异常可能会被抛出许多级别,它会非常巧妙地将你从循环中弹出。在大多数这样的情况下,这有点过于简单化了。通常它太复杂了。 try-catch 块可能很烦人。比如:

            while (readAStringFromFile( in ));
            

            如果readAStringFromFile 有一个地方可以放它读到的东西,写起来会更好更快。

            在您的特定情况下,使用这样的例外可能是您的教授正在寻找的。我个人的经验是,几乎总有比使用 try-catch 块更好的方法来做到这一点,但是当它们真正起作用时,它们的效果非常好。

            【讨论】:

              猜你喜欢
              • 2021-05-13
              • 2012-03-08
              • 1970-01-01
              • 2012-04-07
              • 1970-01-01
              • 2018-07-06
              • 1970-01-01
              • 2011-03-22
              • 1970-01-01
              相关资源
              最近更新 更多