我需要关闭 java.io 包的 Reader 装饰器吗?

发布于 2024-11-04 13:12:32 字数 1021 浏览 2 评论 0原文

我需要解析一个对象,并且需要将收到的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初雪 2024-11-11 13:12:33

如果您记住几个关键点,这并不太复杂:

  • 多次关闭流/读取器/写入器是可以的。第二次(或后续)关闭没有任何效果。
  • 流包装器(PushBackReaderBufferedReader 等)do 在包装器关闭时关闭底层流。
  • 垃圾收集器通常不会自动关闭流,除非该流拥有操作系统资源(文件描述符、套接字等)。
  • 通常,流的创建者会(使用try-finally 块)完成后关闭流,例如
Reader reader = new FileReader(file);
try {
    parse(reader);
} finally {
    reader.close();
}

因此,作为一般规则,parse() 不应关闭读取器,除非有充分的理由这样做(例如,IOException 使流处于不确定状态)如果调用者希望将流用于其他用途。

如果 parse 在完成流后关闭流,这可能不是世界末日,但如果确实如此,那么您绝对应该记录这一事实。

It's not too complicated if you remember a few key points:

  • It's okay to close a stream/Reader/Writer more than once. A second (or subsequent) close has no effect.
  • Stream wrappers (PushBackReader, BufferedReader etc.) do close the underlying stream when the wrapper is closed.
  • The garbage collector does not in general automatically close a stream unless the stream owns on OS resource (file descriptor, socket etc.)
  • Typically the creator of a stream will (using a try-finally block) close the stream when finished with it, e.g.
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 (e.g. an IOException 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.

睫毛溺水了 2024-11-11 13:12:33

最佳实践是始终关闭阅读器 - 如果它们碰巧是其他阅读器的包装器,那么它们应该将关闭操作级联到它们。

在您的代码片段中,只需决定责任所在。有人应该关闭读取器,无论是 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 the parseMyObject method. 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.
(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.

过潦 2024-11-11 13:12:32

如果被调用者将关闭底层 Reader,则无需在 PushbackReader 上调用 close()PushbaseReader 只是一个带有缓冲区的包装器,当您使用完它后,该缓冲区将被垃圾回收。对它调用 close() 将关闭底层的 Reader,如果您希望该方法关闭它,您将需要保留它。

更新:根据您的代码,您似乎无法在 PushbackReader 上调用 close(),因为它还会关闭您的基础 <代码>阅读器。据我所知,如果您这样做,下一次迭代应该会失败,并出现有关流被关闭的异常。例如这个例子失败了:

BufferedReader reader = new BufferedReader(new StringReader("foo"));
new PushbackReader(reader).close();
reader.read(); // IOException: Stream closed

You don't need to call close() on the PushbackReader if the callee will be closing the underlying Reader. The PushbaseReader is just a wrapper with a buffer that'll be garbage collected when you're done with it. Calling close() on it will close the underlying Reader, 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 the PushbackReader because it'll also close your underlying Reader. 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:

BufferedReader reader = new BufferedReader(new StringReader("foo"));
new PushbackReader(reader).close();
reader.read(); // IOException: Stream closed
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文