2014-11-26 5 views
0

내 코드에서 klocwork 코드 분석을 수행했습니다. 다음 오류가 발생했습니다 결국 입력 스트림을 닫았습니다. 오류가 발생하더라도 종료시 'fileInputStream'이 닫히지 않습니다.'fileInputStream'이 종료 할 때 닫히지 않습니다.

다음은 코드

LOGGER.log(Level.INFO, "Inside unzipDownloadedFile method"); 
    File fileDirectory = new File(destDir); 
    FileInputStream fileInputStream = null; 
    // buffer for read and write data to file 
    byte[] buffer = new byte[1024]; 
    ZipInputStream zipInputStream = null; 
    File zipPath = new File(zipFilePath); 
    FileOutputStream fileOutputStream = null; 
    // create output directory if it doesn't exist 
    if (!fileDirectory.exists()) { 
     fileDirectory.mkdirs(); 
    } 
    if (zipPath != null) { 
     if (zipPath.exists()) { 
      try { 
       fileInputStream = new FileInputStream(zipFilePath); 
       zipInputStream = new ZipInputStream(fileInputStream); 
       ZipEntry zipEntry = zipInputStream.getNextEntry(); 
       while (zipEntry != null) { 
        String fileName = zipEntry.getName(); 
        File newFile = new File(destDir + File.separator 
          + fileName); 
        // create directories for sub directories in zip 
        new File(newFile.getParent()).mkdirs(); 
        fileOutputStream = new FileOutputStream(newFile); 
        int zipStream = 0; 
        while ((zipStream = zipInputStream.read(buffer)) > 0) { 
         fileOutputStream.write(buffer, 0, zipStream); 
        } 
        fileOutputStream.close(); 
        // close this ZipEntry 
        zipInputStream.closeEntry(); 
        zipEntry = zipInputStream.getNextEntry(); 
       } 
       fileInputStream.close(); 
      } catch (IOException ioException) { 
       ioException.printStackTrace(); 
      } finally { 
       try { 
        // close last ZipEntry 
        if (zipInputStream != null) { 
         zipInputStream.closeEntry(); 
         zipInputStream.close(); 
        } 
        if (fileInputStream != null) { 
         fileInputStream.close(); 
        } 
        if (fileOutputStream != null) { 
         fileOutputStream.close(); 
        } 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
+0

'zipPath.exists()'테스트는 시간과 공간의 낭비입니다. 'FileInputStream'은 이미이를 테스트하고 이미 catch하고있는 예외를 throw합니다.일을 두 번하는 것은 그것을 추천 할만한 것이 없습니다. – EJP

답변

1

그것은 미묘한의 조각이다, 그러나 당신이 당신의 finally 블록을 자세히 보면, 당신은 zipInputStream, fileInputStreamfileOutputStream을 닫는 예외가 있다면 폐쇄되지 않습니다 것을 볼 수 있습니다. 그리고 fileInputStream을 닫는 예외로 인해 fileOutputStream이 닫히지 않습니다. tryfileInputStream.close()이 포함되어 있어도 기본 코드의 예외로 인해 도달하지 못할 수 있습니다.

} finally { 
    try { 
     // close last ZipEntry 
     if (zipInputStream != null) { 
      zipInputStream.closeEntry(); // An exception here... 
      zipInputStream.close();   // Or here... 
     }         // Prevents all of the following from running 
     if (fileInputStream != null) { 
      fileInputStream.close();  // Similarly, an exception here... 
     } 
     if (fileOutputStream != null) {  // Prevents this from running 
      fileOutputStream.close(); 
     } 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

새로운 try-with-resources 문을 사용하는 것이 좋습니다. ?


아래 요청했습니다 : 내가 자바를 사용하고 따라하면 요구 사항

첫째을 6.Its

이 시도 간단한 사용할 수 없습니다 얻을 누구든지 그 누가 당신에게 그것을 바꿀 것을 요구 했습니까? 2011 년 7 월 28 일   — 3 년 반 전   — 날짜가   6이 Java   7로 바꾼 다음 3 월   18, 2014, Java   8을 Java로 바 꾸었습니다.   7. 적어도 Java   7을 사용하는 것이 좋으며 Java   7은 try-with-resources입니다.

그렇지만 당연히 15 년 동안 Java   1과 Java   7 사이를 처리 할 수있었습니다. 그룹이 아닌 개별적인 닫기 예외를 처리하면됩니다. 나는 StreamHelper 클래스에서 이것을 위해 도우미 함수를 사용했다. 그들은 다음과 같이 보입니다 :

public static InputStream cleanClose(InputStream in) { 
    if (in != null) { 
     try { 
      in.close(); 
     } 
     catch (Exception e) { 
      // ...do something appropriate, but swallow it... 
     } 
    } 
    return null; 
} 

... 그리고 마찬가지로 OutputStream 등입니다. 이 날 세부 방법에 대한 예외를 선언하자, 무엇보다도

InputStream theInput = null; 
OutputStream theOutput = null; 
try { 
    theInput = new FileInputStream(/*...*/); 
    theOutput = new FileOutputStream(/*...*/); 

    // ...do something with the streams 

    // Close them normally 
    theOutput.close(); 
    theOutput = null; 
    theInput.close(); 
    theInput = null; 
} 
finally { 
    // Ensure they're closed 
    theOutput = StreamHelper.cleanClose(theOutput); 
    theInput = StreamHelper.cleanClose(theInput); 
} 

여전히 내 지역 스트림을 처리하는 동안 그들, 전파 할 수 있도록 :

그 때 나는이 패턴을 사용하여, 예외 핸들러에서 사용할 것 세부 방법.

try-with-resources 다른 예외가 발생하는 동안 정리 중에 발생하는 예외는 제기되는 주 예외 ("억제 된"예외라고하며 주요 예외에 해당됨)의 일부가되므로 위와 같은 구식 코드를 사용하면 로깅이나 자신 만의 맞춤형 메커니즘을 사용하여 해당 항목을 알 수 있습니다.

+0

간단한 try를 사용할 수 없습니까? Java 6.Its 요구 사항을 사용하고 있습니다. – kais

+0

이 경우에는 마침내 catch 블록에 finally 코드를 복사해야합니다. – ManojP

+1

Apache Commons-IO를 다운로드 한 다음'finally {IOUtils.closeQuietly (zipInputStream); ...}' – EpicPandaForce

관련 문제