我需要解析一个对象,我需要将我收到的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();
}
答案 0 :(得分:4)
如果被叫方将关闭基础close()
,则无需在PushbackReader
上调用Reader
。 PushbaseReader
只是一个包含缓冲区的包装器,当你完成它时会被垃圾收集。在其上调用close()
将关闭基础Reader
,如果您希望该方法关闭它,则需要保留它。
更新:根据您的代码,您似乎无法在close()
上致电PushbackReader
,因为它也会关闭您的基础Reader
。如果你这样做,我可以看到,下一次迭代应该失败,关于流被关闭的例外。例如。这个例子失败了:
BufferedReader reader = new BufferedReader(new StringReader("foo"));
new PushbackReader(reader).close();
reader.read(); // IOException: Stream closed
答案 1 :(得分:1)
如果你还记得几个关键点,那就太复杂了:
PushBackReader
,BufferedReader
等。)执行在包装器关闭时关闭基础流。try
- finally
块)在完成后关闭流,例如
Reader reader = new FileReader(file);
try {
parse(reader);
} finally {
reader.close();
}
因此,作为一般规则,parse()
不应该关闭读者,除非它有充分理由这样做(例如,IOException
已使流处于不确定状态),以防来电者希望将流用于别的东西。
如果parse
在完成流程后关闭了流,那么可能不是世界末日,但如果确实如此,那么你一定要记录这个事实。
答案 2 :(得分:0)
最佳做法是始终关闭读者 - 如果它们碰巧是其他读者的包装,那么他们应该将关闭操作级联到它们。
在您的代码段中,只需确定责任所在的位置即可。有人应该关闭阅读器,parse
方法或parseMyObject
方法。我更喜欢parse
方法,因为那时代码更具可读性 - 创建/打开阅读器的方法与关闭它的方法相同。
(否则你会遇到奇怪的情况 - 其他人可以使用parseMyObject
,然后突然惊讶于它关闭了读者的论点)
<强>更新强>
现在我看到了你的问题的更新,这归结为在循环中接受一个reader参数,然后多次包装它。我建议你重构代码,这样你只需用PushbackReader包装一次。或者将阅读器的初始化代码移动到内部方法中。