Как правильно повторить попытку метода после обработки исключения? - PullRequest
2 голосов
/ 06 января 2010

Я новичок в исключениях, еще не изучал их в колледже, поэтому все еще узнаю о них. Я попробовал это, и это похоже на работу, но не кажется "правильным". Как правильно повторить попытку метода после обработки исключения?

public static void openCSV(String file) {
    FileInputStream fis;

    try {
        fis = new FileInputStream(file);
    } catch (FileNotFoundException e) { //fnf, probably not downloaded yet.

        downloadCSV(file); //Download it and try again.

        try {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            // OK, something else is the problem.
        }
    }
}

Ответы [ 7 ]

4 голосов
/ 06 января 2010

Ваш вопрос сам по себе не об «исключениях», а скорее о дизайне в целом. Вы получите много-много мнений о правильном способе справиться с этим.

Наиболее очевидное исправление -

if (!new File(file).exists()) {
    downloadCSV(file);
}
try {
    fis = new FileInputStream(file);
} catch (IOException e) {
    // scream
}
2 голосов
/ 06 января 2010

Это форма неправильного использования исключения. Если иногда необходимо загрузить файл, вам не следует полагаться на исключение, сообщающее об этом.

Попробуйте что-то вроде этого:

public static void openCSV(String file) {
    FileInputStream fis;

    try {
        if (!(new File(file).exists())) {
            downloadCSV(file); //download it
        }
        fis = new FileInputStream(file);
        // should probably use the stream here, so you can close it in a finally clause linked to this try clause...
    } catch (FileNotFoundException e) { //file doesnt exist
        // Re-throw as a declared exception, a RuntimeException, and/or log it...
    } finally {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException ioe) {
                // write exception to logs or take other appropriate action...
            }
        }
    }
}
2 голосов
/ 06 января 2010

Мне нравится стараться избегать использования подобных исключений, где я могу помочь. Это один из таких случаев:

public static void openCSV(String file) {
    FileInputStream fis;

   if (!(new File(file).exists())) {
        downloadCSV(file); //download it and try again
    }

    try {
        fis = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        // ok something else is the problem;
    }
}
1 голос
/ 06 января 2010

Вам, вероятно, следует позвонить downloadCSV(file); за пределами openCSV(file). Если FileNotFoundException исключение поймано, вы должны повторно бросить вызывающему. Вы также должны использовать блок finally, чтобы закрыть поток.

0 голосов
/ 06 января 2010

Я не вижу проблемы с кодом. (Кроме того, я бы поставил его в своем собственном методе; не используйте выдуманные аббревиатуры, такие как fis; openCSV, вероятно, должно вызывать исключение и, вероятно, не должно быть статическим.)

Очевидная причина, по которой вы не хотите использовать File.exists, заключается в том, что две операции над путем к файлу не будут атомарными. Это общая проблема с файловыми операциями. Храните вещи как можно более атомарными (обратите внимание, это работает против «делать только одну вещь»). Две операции также могут выполняться медленнее, чем одна.

Кроме того, File.exists может не определить, существует ли файл или нет. Например, у вас могут отсутствовать разрешения на чтение каталога (минимальные разрешения - хорошая вещь).

0 голосов
/ 06 января 2010

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

0 голосов
/ 06 января 2010

В этом сценарии вы неправильно используете обработку исключений для первого блока.

Вы можете просто проверить, существует ли файл в первый раз, а затем попытаться загрузить его.

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