2016-04-23 25 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和它冲洗所以它返回空

相关问题