我需要关闭 java.io 包的 Reader 装饰器吗?
我需要解析一个对象,并且需要将收到的 Reader 包装到 PushbackReader 中。在任何情况下我是否需要关闭 PushbackReader 或者是否足够安全,可以将其保持打开状态,因为它是底层读取器(我没有打开),
或者
public static MyObject parse(Reader reader) throws IOException, ParseException {
PushbackReader pReader = new PushbackReader(reader, PUSHBACK_SIZE);
try {
return parseMyObject(pReader);
} finally {
pReader.close();
}
}
是否足够安全,可以仅写入以下内容:
public static MyObject parse(Reader reader) throws IOException, ParseException {
return parseMyObject(new PushbackReader(reader, PUSHBACK_SIZE));
}
有关信息,以下是如何操作我调用我的解析器:
BufferedReader reader = new BufferedReader(...);
try {
while (...) {
list.add(MyObjectParser.parse(reader));
}
} catch (IOException e) {
throw new RuntimeException("Could not read the stream", e);
} catch (ParseException e) {
throw new ParseRuntimeException("Could not parse the stream", e);
} finally {
// No need for null check.
reader.close();
}
I need to parse an object and I need to wrap the Reader I receive into a PushbackReader. Do I need to close the PushbackReader in any case or is it safe enough to leave it open since it's the underlying reader (that I didn't open) that
With
public static MyObject parse(Reader reader) throws IOException, ParseException {
PushbackReader pReader = new PushbackReader(reader, PUSHBACK_SIZE);
try {
return parseMyObject(pReader);
} finally {
pReader.close();
}
}
Or is it safe enough to write only the following:
public static MyObject parse(Reader reader) throws IOException, ParseException {
return parseMyObject(new PushbackReader(reader, PUSHBACK_SIZE));
}
For info, here's how I call my parser:
BufferedReader reader = new BufferedReader(...);
try {
while (...) {
list.add(MyObjectParser.parse(reader));
}
} catch (IOException e) {
throw new RuntimeException("Could not read the stream", e);
} catch (ParseException e) {
throw new ParseRuntimeException("Could not parse the stream", e);
} finally {
// No need for null check.
reader.close();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您记住几个关键点,这并不太复杂:
PushBackReader
、BufferedReader
等)do 在包装器关闭时关闭底层流。try
-finally
块)完成后关闭流,例如因此,作为一般规则,
parse()
不应关闭读取器,除非有充分的理由这样做(例如,IOException
使流处于不确定状态)如果调用者希望将流用于其他用途。如果
parse
在完成流后关闭流,这可能不是世界末日,但如果确实如此,那么您绝对应该记录这一事实。It's not too complicated if you remember a few key points:
PushBackReader
,BufferedReader
etc.) do close the underlying stream when the wrapper is closed.try
-finally
block) close the stream when finished with it, e.g.So as a general rule
parse()
should not close the reader unless it has a good reason to do so (e.g. anIOException
has left the stream in an indeterminate state) in case the caller wishes to use the stream for something else.It's probably not the end of the world if
parse
closes the stream when it has finished with it, but if it does then you should definitely document the fact.最佳实践是始终关闭阅读器 - 如果它们碰巧是其他阅读器的包装器,那么它们应该将关闭操作级联到它们。
在您的代码片段中,只需决定责任所在。有人应该关闭读取器,无论是
parse
方法还是parseMyObject
方法。我更喜欢parse
方法,因为这样代码更具可读性 - 创建/打开阅读器的方法与关闭它的方法相同。(否则你会遇到奇怪的情况 - 其他人可以使用
parseMyObject
然后突然惊讶地发现它关闭了 reader 参数)更新:
现在我看到了对你的更新问题,这归结为在循环中接受读取器参数,然后多次包装它。我建议您重构代码,以便仅使用 PushbackReader 包装它一次。或者将reader的初始化代码移到内部方法中。
It is best practice that you always close your readers - if they happen to be wrappers to other readers then they should cascade the close operation to them.
In your code snippet, it is just a matter of deciding where the responsibility resides. Someone should close the reader, either the
parse
method or theparseMyObject
method. I prefer theparse
method because then the code is more readable - the same method that created/opened the reader is the one closing it.(otherwise you get into strange situations - someone else can use the
parseMyObject
and then suddenly be surprised that it closed the reader argument)UPDATE:
Now that I see the update to your question, this boils down to accepting a reader parameter in a loop, and then wrapping it multiple times. I suggest that you refactor your code so you wrap it with the PushbackReader only once. Or move the initialization code of the reader into the inner method.
如果被调用者将关闭底层
Reader
,则无需在PushbackReader
上调用close()
。PushbaseReader
只是一个带有缓冲区的包装器,当您使用完它后,该缓冲区将被垃圾回收。对它调用close()
将关闭底层的Reader
,如果您希望该方法关闭它,您将需要保留它。更新:根据您的代码,您似乎无法在
PushbackReader
上调用close()
,因为它还会关闭您的基础 <代码>阅读器。据我所知,如果您这样做,下一次迭代应该会失败,并出现有关流被关闭的异常。例如这个例子失败了:You don't need to call
close()
on thePushbackReader
if the callee will be closing the underlyingReader
. ThePushbaseReader
is just a wrapper with a buffer that'll be garbage collected when you're done with it. Callingclose()
on it will close the underlyingReader
, which you'll want to keep if you expect the method to be closing it.Update: Based on your code it looks like you can't call
close()
on thePushbackReader
because it'll also close your underlyingReader
. The next iteration should fail with an exception about the stream being closed if you do that, from what I can see. E.g. this example fails: