Подтвердить что ты не робот

Могу ли я избежать такой громоздкой попытки... catch block

Обычно, когда речь идет о Java IO-коде, вот что я написал

    FileOutputStream out = null;
    try
    {
        out = new FileOutputStream("myfile.txt");
        // More and more code goes here...
    }
    catch (Exception e)
    {
    }
    finally 
    {
        // I put the close code in finally block, to enture the opened
        // file stream is always closed even there is exception happened.
        if (out != null) {
            // Another try catch block, troublesome.
            try {
                out.close();
            } catch (IOException ex) {
            }
        }
    }

Как вы можете видеть, когда я пытаюсь закрыть поток файлов, мне нужно иметь дело с другим блоком try... catch.

Посмотрите на беспокойство: (

Есть ли способ избежать? Я не чувствую себя комфортно в том, чтобы поместить закрытый код в блок без окончания, поскольку исключение, вызванное другими кодами, не даст никаких шансов для вызова "close".

4b9b3361

Ответ 1

Очень важно, чтобы вы закрыли потоки в конце. Вы можете упростить этот процесс с помощью утилиты, например:

public static void closeStream(Closeable closeable) {
    if(null != closeable) {
      try {
        closeable.close();
      } catch(IOException ex) {
        LOG.warning("Failed to properly close closeable.", ex);
      }
    }
  }

Я делаю это точкой, по крайней мере, протоколированием сбоя потока. Затем использование будет:

FileOutputStream out = null;
try
{
    out = new FileOutputStream("myfile.txt");
    // More and more code goes here...
}
catch (Exception e)
{
}
finally 
{
    closeStream(out);
}

В Java 7 я считаю, что потоки будут автоматически закрыты, а необходимость в таких блоках должна быть в основном избыточной.

Ответ 2

Автоматическое управление ресурсами входит в Java 7, который автоматически обеспечит обработку этого. До тех пор объекты, такие как OutputStream, InputStream и другие реализуют интерфейс Closeable с Java 5. Я предлагаю вам предоставить утилиту метод для их безопасного закрытия. Эти методы обычно содержат исключения, поэтому убедитесь, что вы используете их только тогда, когда хотите игнорировать исключения (например, в методе finally). Например:

public class IOUtils {
    public static void safeClose(Closeable c) {
        try {
            if (c != null)
                c.close();
        } catch (IOException e) {
        }
    }
}

Обратите внимание, что метод close() может быть вызван несколько раз, если он уже закрыт, последующие вызовы не будут иметь эффекта, поэтому также вызывают вызов для закрытия во время нормальной работы блока try, где исключение не будет игнорироваться, Из документации Closeable.close:

Если поток уже закрыт, вызов этого метода не имеет эффекта

Закройте выходной поток в регулярном потоке кода, а метод safeClose будет работать только в том случае, если что-то не удалось в блоке try:

FileOutputStream out = null;
try {
    out = new FileOutputStream("myfile.txt");
    //... 
    out.close();
    out = null;
} finally {
    IOUtils.safeClose(out);
}

Ответ 4

Проект Lombok предоставляет аннотацию @Cleanup, которая устраняет необходимость блокировки try catch. Вот пример.

Ответ 5

Я обычно использую функции утилиты для этого:

public static void safeClose(OutputStream out) {
  try {
    out.close();
  } catch (Exception e) {
    // do nothing
  }
}

который изменяет код на несколько более приемлемый:

FileOutputStream out = null;
try {
  out = new FileOutputStream("myfile.txt");
  // do stuff
} catch (Exception e) {
  // do something
} finally {
  safeClose(out);
}

Вы действительно не можете сделать намного лучше в Java, по крайней мере, до Java 7, когда (надеюсь) Блокировка ARM ( "Автоматическое управление ресурсами" ) поможет несколько.

Ответ 6

Напишите метод, который выглядит примерно так: вызов из вашего блока finally...

static void wrappedClose(OutputStream os) {
  if (os != null) {
    try {
      os.close();
    }
    catch (IOException ex) {
       // perhaps log something here?
    }
  }

Ответ 7

Разделите блоки try/catch и try/finally.

try
{
    FileOutputStream out = new FileOutputStream("myfile.txt");
    try
    {
        // More and more code goes here...
    }
    finally 
    {
        out.close();
    }
}
catch (Exception e)
{
    //handle all exceptions
}

Внешний улов также поймает все, что бросает закрытие.