3

我有一个 xml 文件存储在数据库 blob 中,用户将通过 spring/hibernate Web 应用程序下载该文件。在通过 Hibernate 将其作为 byte[] 检索后,但在将其发送到输出流之前,我需要编辑 XML 的某些部分(具有两个子节点和一个属性的单个节点)。

我担心的是如果文件更大(有些是 40mb+),那么我真的不想通过将整个文件放在内存中,编辑它然后通过输出流将它传递给用户来做到这一点。有没有办法“即时”编辑它?

byte[] b = blobRepository.get(blobID).getFile();
// What can I do here?
ServletOutputStream out = response.getOutputStream();
out.write(b);
4

2 回答 2

2

您可以使用 SAX 流。

使用 SAX 框架解析文件,当您的处理程序接收到 SAX 事件时,将未更改的项目传回给构造 XML 输出的 SAX 处理程序。

当您到达“要更改的部分”时,您的中间类将读入不需要的事件,并写出想要的事件。

这样做的好处是不会将整个文件作为中间表示(比如 DOM)保存在内存中;但是,如果转换很复杂,您可能必须缓存许多项目(文档的部分),以使它们可用于重新排列的输出。一个足够复杂的转换(一个可以做任何事情的转换)最终会变成 DOM 的开销,但是如果您知道您忽略了文档的大部分,则可以节省大量内存。

于 2012-07-26T15:24:12.577 回答
2

您可以尝试以下方法:

  1. 在 Hibernate 中启用二进制数据流(将hibernate.jdbc.use_streams_for_binary设置为 true)
  2. 使用ent.getBlob().getBinaryStream()将 xml 文件作为二进制流接收
  3. 使用支持流式处理(例如 saxon)的 XSTL 处理器处理输入流,将输出直接重定向到 servlet OutputStream:javax.xml.transform.Transformer.transform( SAXSource , new StreamResult(response.getOutputStream()))
于 2012-07-26T15:44:10.950 回答