[英]Do I need to close a Reader decorator of the java.io package?
I need to parse an object and I need to wrap the Reader I receive into a PushbackReader.我需要解析 object 并且需要将收到的 Reader 包装到 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
我是否需要在任何情况下关闭 PushbackReader 或者是否足够安全以使其保持打开状态,因为它是底层阅读器(我没有打开)
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();
}
You don't need to call close()
on the PushbackReader
if the callee will be closing the underlying Reader
.如果被调用者将关闭底层
Reader
,则无需在PushbackReader
上调用close()
。 The PushbaseReader
is just a wrapper with a buffer that'll be garbage collected when you're done with it. PushbaseReader
只是一个带有缓冲区的包装器,当你完成它时会被垃圾收集。 Calling close()
on it will close the underlying Reader
, which you'll want to keep if you expect the method to be closing it.对其调用
close()
将关闭底层Reader
,如果您希望该方法将其关闭,您将希望保留它。
Update : Based on your code it looks like you can't call close()
on the PushbackReader
because it'll also close your underlying Reader
.更新:根据您的代码,您似乎无法在
PushbackReader
上调用close()
,因为它也会关闭您的底层Reader
。 The next iteration should fail with an exception about the stream being closed if you do that, from what I can see.从我所见,下一次迭代应该会失败,但如果你这样做,stream 将被关闭。 Eg this example fails:
例如,此示例失败:
BufferedReader reader = new BufferedReader(new StringReader("foo"));
new PushbackReader(reader).close();
reader.read(); // IOException: Stream closed
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. PushBackReader
, BufferedReader
等)在包装器关闭时关闭底层 stream 。try
- finally
block) close the stream when finished with it, egtry
- finally
块)在完成 stream 后关闭它,例如Reader reader = new FileReader(file);
try {
parse(reader);
} finally {
reader.close();
}
So as a general rule parse()
should not close the reader unless it has a good reason to do so (eg an IOException
has left the stream in an indeterminate state) in case the caller wishes to use the stream for something else.因此,作为一般规则
parse()
不应关闭阅读器,除非它有充分的理由这样做(例如, IOException
使 stream 处于不确定状态),以防调用者希望将 stream 用于其他目的。
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
完成后关闭 stream 可能不是世界末日,但如果确实如此,那么您绝对应该记录这一事实。
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 the parseMyObject
method.有人应该关闭阅读器,无论是
parse
方法还是parseMyObject
方法。 I prefer the parse
method because then the code is more readable - the same method that created/opened the reader is the one closing it.我更喜欢
parse
方法,因为这样代码更具可读性 - 创建/打开阅读器的相同方法是关闭它的方法。
(otherwise you get into strange situations - someone else can use the parseMyObject
and then suddenly be surprised that it closed the reader argument) (否则你会遇到奇怪的情况——其他人可以使用
parseMyObject
然后突然惊讶于它关闭了 reader 参数)
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.
我建议你重构你的代码,这样你只用 PushbackReader 包装它一次。 Or move the initialization code of the reader into the inner method.
或者将阅读器的初始化代码移动到内部方法中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.