Java: Как продолжить чтение файла после возникновения исключения - PullRequest
3 голосов
/ 13 декабря 2011

поэтому мой профессор назначил нам проект, в котором мы должны брать команды из текстового файла и использовать их для управления потоком нашей программы. Такие команды, как взлет, посадка, загрузка груза, выгрузка груза и т. Д., Предназначены для имитации объекта, подобного самолету.

Иногда выполнение этих команд не имеет смысла, например загрузка груза, когда самолет находится в полете. Поэтому, чтобы предотвратить что-то подобное, нам пришлось кодировать в наших собственных классах исключений, т. Е. "Если самолету приказано загружать груз во время полета, выведите 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
        }
    }

Буду признателен за любую помощь. Спасибо.

Ответы [ 8 ]

3 голосов
/ 13 декабря 2011

видя, как после того, как они выброшены, программа внезапно завершается

Только неперехваченное исключение останавливает поток.Я предлагаю вам перехватить все исключения, после которых вы хотите продолжить, и у вас не возникнет проблем.

3 голосов
/ 13 декабря 2011

Catch соответствующее исключение, и поток автоматически достигнет while условия цикла.

После создания исключения не нужно ничего делать для продолжения программы.

2 голосов
/ 13 декабря 2011

Поскольку ваш catch находится внутри цикла while, цикл, естественно, продолжит следующую итерацию после того, как исключение будет перехвачено.

2 голосов
/ 13 декабря 2011

Это именно то, что вы хотите сделать. Все операторы чтения и обработки помещаются в блок try, а в блоке catch содержится только обработка ошибок (которая может состоять из чего-то кроме печати предупреждающего сообщения где-либо.

Вы должны быть осторожны, чтобы не застрять в бесконечной петле. Убедитесь, что каждый раз во время цикла вы обрабатываете новые данные!

2 голосов
/ 13 декабря 2011

Поймайте ваше конкретное исключение:

while(input.hasNextLine())
{
    try 
    {
         //execute commands by reading them using input.nextLine()
    }
    catch ( UserDefinedException ex )
    {
         //catch the exceptions you're throwing
    }
}
1 голос
/ 13 декабря 2011

Чтобы добавить к другим ответам: исключения могут выполнять ряд заданий. Слишком часто они говорят вам, что ваша программа безнадежно нестабильна и должна немедленно закрыться.

Обычно они сообщают вам, что случилось что-то плохое и неожиданное, и дают вам возможность объяснить проблему пользователю, а затем продолжить. Например, неожиданное исключение конца файла. Вы можете сказать пользователю, что файл плохой, и позволить ему попробовать другой. Вы также можете распечатать трассировку стека, чтобы они могли вам позвонить и выяснить, что произошло, даже если вы не распечатали подробное сообщение об ошибке.

Обратите внимание на раздвоение личности этого исключения. Подобно первому типу (обычно экземплярам RunTimeException), они сообщают вам точно, что произошло почти без вашего участия. Тем не менее, Java также заставил вас знать, что IOException может быть брошен, и попытался заставить вас написать приятное сообщение для пользователя. Я всегда был немного озадачен этим. Если я ловлю EOFException, я знаю , где это произошло, и мне не нужна трассировка стека. (Конечно, если я знаю, что EOF не может произойти, я не буду беспокоиться о правильном сообщении пользователю, и трассировка стека, когда это произойдет, будет очень полезна.)

Но есть и третий тип исключения, второй тип предыдущего исключения. Это просто дает вам знать, что произошло нечто совершенно нормальное. Это очень эффективно (если вы настроили его правильно, см. Ниже). И это может быть намного чище, чем возвращать значения в стек вызовов методов. Он позволяет методу, который уже возвращает, скажем, String (с нулевой ссылкой, которая вполне подходит), чтобы предупредить вызывающий метод о специальном условии и, необязательно, предоставить огромные объемы данных об этом условии.

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, но когда они работают, они работают очень хорошо.

1 голос
/ 13 декабря 2011

Набросок, который вы показали, достаточен для достижения того, что вы хотите (т.е. конструкция try-catch находится внутри цикла while). Просто убедитесь, что оператор catch объявляет правильный тип или супертип исключения, которое вы хотите перехватывать и игнорировать.

ОБНОВЛЕНИЕ: Если вы не знаете, какое исключение нужно отловить, вы можете захотеть использовать «Throwable», но это не очень рекомендуется. Когда ваш учитель заставлял вас реализовывать свои собственные исключения, вы, вероятно, основывали их на одном существующем классе исключений. Возможно, вы захотите поймать этот тип исключения.

И на совершенно другой ноте, вы можете прочитать все команды из текстового файла в список строк перед выполнением последовательности. Это может избавить вас от некоторых проблем с вводом-выводом, потому что вы постоянно держите дескриптор файла (что кажется ненужным для такой простой задачи).

1 голос
/ 13 декабря 2011

Любое исключение, пойманное в ваших блоках 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, вероятно, должно привести к завершению программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...