У меня есть ошибка «Метод может не очистить поток или ресурс» в FindBugs, и я не знаю, как решить эту ошибку, так что может ли кто-нибудь решить ее, пожалуйста?

#findbugs #spotbugs

Вопрос:

Этот метод может не выполнить очистку (закрытие, удаление) потока, объекта базы данных или другого ресурса, требующего явной операции очистки. В общем случае, если метод открывает поток или другой ресурс, метод должен использовать блок try/finally, чтобы убедиться, что поток или ресурс очищены до того, как метод вернется.

Это и есть код:

 public void setSource(File file) throws IOException {

 m_structure = null;
 setRetrieval(NONE);

 if (file == null) {
  throw new IOException("Source file object is null!");
 }

 try {
  setSource(new FileInputStream(file));
 } 
 catch (FileNotFoundException ex) {
  throw new IOException("File not found");
 }
 
 m_File = file.getAbsolutePath();
}
 

Ответ №1:

Вы получаете сообщение об ошибке из-за следующей строки:

new FileInputStream(file)

Теоретически вы могли бы закрыть входной поток внутри setSource(InputStream is) метода, однако это неверная область. Соглашение заключается в том, чтобы закрыть поток там, где вы его открыли. Поэтому, если вы измените свой код на следующий, он должен удалить предупреждение. Пожалуйста, обратите внимание, что ваш блок catch не имеет смысла, так FileNotFoundException как он уже есть IOException . Есть две возможности:

  1. Попробуйте с помощью ресурсов:
     public void setSource(File file) throws YourOwnApplicationException{
    
     if (file == null) {
      throw new YourOwnApplicationException("Source file object is null!");
     }
    
     try (FileInputStream fis=new FileInputStream(file)){
      setSource(fis);
     } 
     catch (IOException | FileNotFoundException ex) {
      throw new YourOwnApplicationException("File not found");
     }
    }
     
  2. Способ до Java 7/8:
     public void setSource(File file) throws YourOwnApplicationException {
    
     if (file == null) {
      throw new YourOwnApplicationException ("Source file object is null!");
     }
    
     FileInputStream fis=null;
     try {
         fis = new FileInputStream(file);
         setSource(fis);
     } 
     catch (IOException | FileNotFoundException ex) {
      throw new YourOwnApplicationException("File not found");
     }
     finally {
         if(fis!=null) {
             try {
                 fis.close();
             }
             catch(IOException ioe) {
                 //swallow
             }
         }
     }
    }
     

Если вы делаете это так, это также означает, что вы должны использовать свой InputStream внутренний setSource(InputStream is) метод. В противном случае не имело бы смысла закрывать его…