2017-10-06 48 views
0

聲納引發了fileStream未在下面的代碼中關閉的問題。但是,它是在lambda表達式中。如何解決聲納問題:當流真的關閉,但在lambda中時,流並未關閉

try { 
       final InputStream fileStream = new FileInputStream(copy); 
       return (OutputStream outputStream) -> { 
        int n; 
        byte[] buffer = new byte[1024]; 
        while ((n = fileStream.read(buffer)) > -1) { 
         outputStream.write(buffer, 0, n); 
        } 
        fileStream.close(); 
       }; 
      } catch (IOException exception) { 
       ... 
      } 

當我改變它,使用try-與資源模式,然後我得到異常:產生java.io.IOException:流閉閱讀FILESTREAM線:

try (final InputStream fileStream = new FileInputStream(copy)) {     
      return (OutputStream outputStream) -> { 
       int n; 
       byte[] buffer = new byte[1024]; 
       while ((n = fileStream.read(buffer)) > -1) { 
        outputStream.write(buffer, 0, n); 
       }      
      }; 
     } catch (IOException exception) { 
      ... 
     } 

因此第二個解決方案解決了sonar檢測到的bug,但是它只是在lambda代碼被調用之前關閉fileStream時不起作用。

你會建議如何解決它?

+0

如果發生異常,該方法可能會在outputStream.close()調用完成之前跳出。將close命令添加到catch塊或使用try-with-resource來解決此問題。 – Korashen

回答

0

正如@Krashen在評論中指出的那樣,在調用close()之前,您的第一個版本可能會拋出異常。

您的版本版本在這個方法中嘗試使用資源嘗試創建InputStream,然後嘗試將其作爲lambda表達式的一部分返回。但是,試用資源確保其資源是封閉的,並且據我所知,在方法退出之前會發生關閉。顯然,在呼叫方收到return時,InputStream已經關閉。

所以......你最好的選擇是從lambda中提取你的邏輯並返回結果,或者將lambda結果賦值給一個變量,然後返回該變量。做後者可能會引起S1488的問題(局部變量不應該被聲明,然後立即返回或拋出),我會簡單地關閉Will not Fix。