问题描述
我正在编写一个方法,但看到此错误:可能无法关闭流。 根据不同帖子上的一些解决方案,我在 finally 块中添加了 try 和 catch。我还添加了 IoUtils.closeQuietly(fullObject,(Log) LOGGER)。但它仍然不起作用。有谁可以帮忙看看吗?谢谢!
S3Object fullObject = null;
StringBuffer buffer = new StringBuffer();
try {
S3Object s3Response = s3Client.getobject(s3BucketName,s3Key);
BufferedReader reader = new BufferedReader(new InputStreamReader(s3Response.getobjectContent()));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
} finally {
if (fullObject != null) {
try {
fullObject.close();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
IoUtils.closeQuietly(fullObject,(Log) LOGGER);
}
}
return buffer.toString();
}
解决方法
InputStreamReader
实现 AutoCloseable
。这意味着预期用途是 try-with-resources
:
try (InputStreamReader reader = new InputStreamReader(s3Response.getObjectContent()) {
...
}
无论块如何退出(即通过正常完成、catch
或 finally
子句),这都应始终关闭流。
S3Object
和 BufferedReader
也是如此。它们都可以在同一个 try
块中声明为资源。
有关详细信息,请参阅 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html。
,您应该使用 Java 7+ try with resources。它将负责关闭您在列表中声明的资源。关闭过程中可能抛出的任何异常都会得到适当的处理。 (如果异常已经在传播,它们要么被允许传播,要么被“抑制”。)
您使用尝试资源的代码如下所示。它是原始版本的一半长度,并且不会有任何资源泄漏。你“双赢”。
const arr = [
{
rooms: ['f03e6e40-870d-11eb-88a2-0149a30c02c5'],itemType: 'Item',id: '8c6a6070-80c0-11eb-9753-bb149505e85f',itemName: 'Item 1',},{
rooms: ['eef60fc0-870d-11eb-88a2-0149a30c02c5'],id: '3aede320-870f-11eb-9e58-9d6fb0d8b5a8',itemName: 'Item 2',{
rooms: ['f03e6e40-870d-11eb-88a2-0149a30c02c5'],id: '3ad52b00-870f-11eb-8f84-0782ebd81006',itemName: 'Item3',{
itemType: 'Room',id: 'f03e6e40-870d-11eb-88a2-0149a30c02c5',itemName: 'Bedroom',id: 'eef60fc0-870d-11eb-88a2-0149a30c02c5',itemName: 'Bedroom 2',]
const result = arr.map((element) => {
if (element.itemType !== 'Room') {
return element
}
return {
...element,count: arr.filter(
(i) => i.itemType === 'Item' && i.rooms.includes(element.id)
).length,}
})
console.log(result)
请注意,我已经删除了您的代码未使用的 try (S3Object s3Response = s3Client.getObject(s3BucketName,s3Key);
BufferedReader reader = new BufferedReader(
new InputStreamReader(s3Response.getObjectContent()));
)
{
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
}
。
上面实际上有两个托管资源:fullObject
和 s3Response
。关闭它们可能不是绝对必要的,但是 (IMO) 无论如何关闭它们是正确的做法......从可读性的角度来看,如果没有别的。
(也可以更简单和/或更有效地执行“将内容作为字符串读取”,但这超出了本问题的范围。)