【问题标题】:Write a StringBuilder to a Writer, without toString()将 StringBuilder 写入 Writer,无需 toString()
【发布时间】:2012-09-24 21:13:53
【问题描述】:

在 Servlet 中,我在 StringBuilder 中构建大量 HTML 内容,最后需要将其写入响应的 PrintWriter。为了使用 PrintWriter,它必须首先调用 StringBuilder 的 toString() 方法以获取 String 形式的内容。但这不必要地复制了内容。有什么方法可以直接从 StringBuilder 写入,因为它已经保存了内容?

PrintWriter 可以接受 CharSequence,但文档说明它调用 CharSequence 的 toString(),所以它并没有真正的帮助。

我能看到的唯一明确的方法是使用 StringBuilder 的 charAt(i) 方法一次获取和写入一个字符,但这会是一种改进吗?

【问题讨论】:

  • 改进是相对的。如果您的目标是减少内存消耗,那么是的,这将是一个改进。你应该测试它是否更慢。如果 - 由于输出流的缓冲 - 毕竟性能损失并没有那么大,我不会感到惊讶。

标签: java servlets stringbuilder printwriter


【解决方案1】:

作为替代方案,您可以删除 StringBuilder 并使用 StringWriterPrintWriter

【讨论】:

  • 我需要把HTML内容写到Servlet的PrintWriter中,通过调用HttpServletResponse的getWriter()方法得到。我没有看到将它与 StringWriter 结合起来的方法。
【解决方案2】:

您可以首先写入 PrintWriter 而不是 StringBuilder...

使用charAt 绝对不会帮助您。这样做会产生非常糟糕的性能。 如果您真的想朝那个方向前进,您可以使用StringBuilder.subString(start,end) 方法。此方法将允许您一次读取例如 1000 个字符并将其打印到 PrintWriter...

【讨论】:

  • StringBuilder.substring() 将在您每次调用它时分配一个新字符串。尽管分配的内存总量会更小,但它仍然会带来很多开销。我实际上认为使用 charAt() 不会那么糟糕,因为很可能 Servlet 的 PrintWriter 无论如何都会被缓冲。
【解决方案3】:

StringBuilder 类将字符串存储在内部 char 数组中。问题是这个 char 数组不可访问。

建议的解决方案:

1) 您可以创建一个扩展 ObjectOutputStream 的新类,在其中覆盖 writeObjectOverride(Object obj) 方法。然后简单地序列化您构建 HTML 文档的 StringBuilder 实例。 您重写的 writeObjectOverride(Object obj) 方法将使用 Stringbuilder 的内部 char 数组调用,这是序列化过程的一部分,瞧:您拥有对 String 构建器的内部 char 数组的引用,您可以将其写入Servlet 的 PrintWriter 输出... 注意: 您的 writeObjectOverride() 方法将被多次调用,显然您可以忽略那些传递给您所需字符数组以外的东西的方法。

2) 您可以使用CharBuffer 类而不是StringBuilder,后者具有返回内部数组的array() 方法。 CharBuffer 没有 StringBuilder 那么多的追加(或放置)操作,因此需要稍微扩展这些操作(取决于您的确切需要)...

3) 您可以编写自己的StringBuilder 实现,或者更确切地说,您可以从中使用什么。这样您就可以访问存储组合文本的对象(例如 char 数组)...

【讨论】:

  • 我不确定解决方案 1 是否可行,因为要使用 writeObjectOverride,您需要重写大部分序列化逻辑,因为一个参数 ObjectOutputStream 构造函数会禁用对 writeObjectOverride 的调用。即它不是为这种方式设计的。此外,您无法在 writeObjectOverride 中调用其他方法来处理正常情况。虽然您可以使用反射,但安全管理器可能会妨碍您。
猜你喜欢
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 2022-07-23
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多