2016-04-23 23 views
1

我有以下兩個代碼塊,我用它來壓縮一個字符串。不同的行爲當返回的地方內部和嘗試後

代碼1

public static String compressResponse(String response) throws IOException { 

    Deflater deflater = new Deflater(Deflater.DEFLATED, true); 
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater); 
    try { 
     deflaterOutputStream.write(response.getBytes(StandardCharsets.UTF_8)); 
     return Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES); 
    } finally { 
     deflaterOutputStream.close(); 
    } 
} 

代碼2

public static String compressResponse(String response) throws IOException { 

    Deflater deflater = new Deflater(Deflater.DEFLATED, true); 
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
    DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater); 
    try { 
     deflaterOutputStream.write(response.getBytes(StandardCharsets.UTF_8)); 
    } finally { 
     deflaterOutputStream.close(); 
    } 
    return Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES); 
} 

只有第二方法正常工作,其中第一方法總是返回空字符串。我知道這種不同的行爲是由於不同的返回塊相對於finally塊的放置而發生的。這是什麼確切的行爲?

+4

的['close'的Javadoc](https://docs.oracle.com/javase/8/docs/api/java/util/ zip/DeflaterOutputStream.html#close--)表示*將剩餘的壓縮數據寫入輸出流並關閉底層流*。據推測,如果你沒有關閉,剩下的*數據(即全部)還沒有被寫入流中(另見['flush'](https://docs.oracle.com/) JavaSE的/ 8 /文檔/ API/JAVA/util的/壓縮/ DeflaterOutputStream.html#flush--))。另外,我更喜歡['try-with-resources'](http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)。 –

+0

@ElliottFrisch「*還有其他數據(即全部)*」是不是?我知道如果我們不叫''close()''仍然有很大的機會傳輸一些數據流;關閉()確保獲得100%的數據。我錯了嗎? –

+0

@rev_dihazum它的緩衝;如果你不'沖洗'它可能有任何(或沒有)的內容保留在緩衝區中。這可能會導致非常困難的錯誤。 –

回答

0

的原因是因爲在第一種方法雖然第二辦關閉操作第一

deflaterOutputStream你做deflaterOutputStream.close();之前執行return語句時,它關閉連接將數據寫入byteArrayOutputStream。直到deflaterOutputStream已關閉,byteArrayOutputStream不包含數據。

+0

如何在返回後關閉deflaterOutputStream影響方法的輸出?如果它沒有關閉,仍然Base64.encodeBytes(byteArrayOutputStream.toByteArray(),Base64.DONT_BREAK_LINES)應該返回一個正確的值,不是嗎? –

+0

不,這是假設,如果你不關閉它,它不會釋放內存,不會寫入,這意味着它不會返回正確的值... – Dazak

+0

因此,當我們關閉deflatedOutputStream時,它會將值寫入/清空到byteArrayOutputStream? –

2

在第二個示例中,byteArrayOutputStream被填充,因爲deflaterOutputStream已關閉,而已刷新爲

-1

即使你放在return語句try塊,你終於塊將執行,finally塊的功能,

如果發生異常或不提高,即使如果發生異常,並處理或不處理,然後finally塊將執行,最終如果你把system.exit()trycatch

在你的代碼塊將不執行

try{ 
return------> this wont return instead finally block will execute 
} 
finally{ 
// 
} 

你的閉合DeflaterOutputStream和它沖洗所以它返回空

相關問題