2016-12-16 2 views
2

Нужно ли определять двоичный объект отдельно, поэтому я могу позвонить ему .dispose(); (см. methodOne()) или будет обрабатываться автоматически при автоматическом закрытии InputStream (см. methodTwo())?Мне нужно вызвать оба .dispose() (javax.jcr.Binary) и .close() (java.io.InputStream)?

private void methodOne(Resource resource) { 
    Binary binary = resource.getValueMap().get("jcr:data", Binary.class); 
    try { 
     InputStream is = null; 
     try { 
      is = binary.getStream(); 
      // ...do something with the InputStream... 
     } catch (RepositoryException e) { 
      LOG.error("RepositoryException trying to get an InputStream from the resource."); 
     } finally { 
      if (is != null) { 
       IOUtils.closeQuietly(is); 
      } 
     } 
    } finally { 
     binary.dispose(); 
    } 
} 

private void methodTwo(Resource resource) { 
    try (InputStream is = resource.getValueMap().get("jcr:data", Binary.class).getStream()) { 
     // ...do something with the InputStream... 
    } catch (IOException e) { 
     LOG.error("IOException from trying to auto-close InputStream."); 
    } catch (RepositoryException e) { 
     LOG.error("RepositoryException trying to get an InputStream from the resource."); 
    } 
} 

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

ответ

4

Если класс, который вы получаете поток из документов, которые закрывают поток, достаточен, вам необходимо убедиться, что вы перечислите другие закрывающиеся ресурсы в try, чтобы получить try-with-resources, чтобы закрыть их для вас.

Вы сказали, что Binary не реализует AutoCloseable. Раздражает. :-) Вы всегда можете определить обертку (как я предполагаю, что это не единственное место, где вы должны иметь дело с этим), то вдоль этих линий:

public class ACBinaryWrapper implements AutoCloseable { 
    private Binary binary; 

    public ACBinaryWrapper(Binary binary) { 
     this.binary = binary; 
    } 

    public Binary getBinary() { 
     return this.binary; 
    } 

    public void close() { 
     if (this.binary != null) { 
      Binary b = this.binary; 
      this.binary = null; 
      b.dispose(); 
     } 
    } 
} 

Тогда:

private void yourMethod(Resource resource) { 
    try (
     ACBinaryWrapper acbinary = new ACBinaryWrapper(
      resource.getValueMap().get("jcr:data", Binary.class) 
     ); 
     InputStream is = acbinary.getBinary().getStream(); 
    ) { 
     // ...do something with the InputStream... 
    } catch (IOException e) { 
     // ...appropriate handling... 
    } catch (RepositoryException e) { 
     // ...appropriate handling... 
    } 
} 

Примечание как binary указан отдельно от is.


Ваши LOG заявление в IOException обработчика и такой, казалось, предположит, что единственная ошибка ввода/вывода, который может произойти была при закрытии потока. В общем, чтение из потоков также может привести к ошибке ввода-вывода.

+0

Большое спасибо за разъяснение по обработке IOException, а также быстрый ответ! javax.jcr.Binary не расширяет Closeable или AutoCloseable, поэтому объявление в объявлении try-with-resources не обязательно будет обрабатывать вызов '.dispose();' хотя, правильно? – Gdubz

+1

@gdubz: Извините, моя ошибка, я предположил, что это «AutoCloseable». Одна секунда ... –

+0

Все в порядке. Читая комментарии в классе, похоже, что я отвечаю за вызов как .close() 'на InputStream, так и' .dispose() 'на самом двоичном объекте. Я просто не понимаю последствия вызова '.getStream()' от прикованной инициализации (думаю, оставляю там анонимный двоичный объект?) Или как даже тестировать/отлаживать это. – Gdubz

Смежные вопросы