我正在开发一个 Java Web 应用程序,其中文件将存储在数据库中。最初,我们通过简单地在结果集上调用 getBytes
来检索数据库中已有的文件:
byte[] bytes = resultSet.getBytes(1);
...
然后使用明显的构造函数将该字节数组转换为 DataHandler
:
dataHandler = new DataHandler(bytes, "application/octet-stream");
这非常有效,直到我们开始尝试存储和检索更大的文件。将整个文件内容转储到字节数组中,然后从中构建 DataHandler 只需要太多内存。
我的直接想法是使用 getBinaryStream
检索数据库中的数据流,并以某种方式将 InputStream
转换为内存高效的 DataHandler
方式。不幸的是,似乎没有直接的方法将 InputStream
转换为 DataHandler
。我一直在尝试的另一个想法是从 InputStream
读取数据块并将它们写入 DataHandler
的 OutputStream
。但是......我找不到一种方法来创建一个“空”DataHandler
,当我调用 getOutputStream
时返回非空 OutputStream
……
有人做过吗?我很感激您能给我的任何帮助或引导我走向正确的方向。
I'm working on a Java web application in which files will be stored in a database. Originally, we retrieved files already in the DB by simply calling getBytes
on our result set:
byte[] bytes = resultSet.getBytes(1);
...
This byte array was then converted into a DataHandler
using the obvious constructor:
dataHandler = new DataHandler(bytes, "application/octet-stream");
This worked great until we started trying to store and retrieve larger files. Dumping the entire file contents into a byte array and then building a DataHandler
out of that simply requires too much memory.
My immediate idea is to retrieve a stream of the data in the database with getBinaryStream
and somehow convert that InputStream
into a DataHandler
in a memory-efficient way. Unfortunately it doesn't seem like there's a direct way to convert an InputStream
into a DataHandler
. Another idea I've been playing with is reading chunks of data from the InputStream
and writing them to the OutputStream
of the DataHandler
. But... I can't find a way to create an "empty" DataHandler
that returns a non-null OutputStream
when I call getOutputStream
...
Has anyone done this? I'd appreciate any help you can give me or leads in the right direction.
发布评论
评论(8)
Kathy Van Stone 的答案的实现< /a>:
首先,创建一个帮助器类,该类从输入流创建数据源:
然后您可以从输入流创建数据处理程序:
导入:
An implementation of the answer from Kathy Van Stone:
At first, create a helper class, which creates a DataSource from an InputStream:
And then you can create a DataHandler from an InputStream:
imports:
我也遇到了这个问题。如果您的源数据是
byte[]
,则 Axis 已经有包装 InputStream 并创建 DataHandler 对象的类。这是代码相关导入
I also ran into this issue. If your source data is a
byte[]
, Axis already has a class that wraps the InputStream and creates a DataHandler object. Here is the codeRelated imports
我的方法是编写一个自定义类,实现包装您的
InputStream
的DataSource
。然后创建DataHandler
,为其提供创建的DataSource
。My approach would be to write a custom class implementing
DataSource
that wraps yourInputStream
. Then create theDataHandler
giving it the createdDataSource
.注意DataSource的getInputStream每次调用都必须返回一个新的InputStream。这意味着您需要先将其复制到某个地方。
有关更多信息,请参阅
https://bugs.java.com/bugdatabase/view_bug?bug_id=4267294
Note that the getInputStream of the DataSource must return a new InputStream every time called. This means you need to copy it somewhere first.
For more information, see
https://bugs.java.com/bugdatabase/view_bug?bug_id=4267294
bugs_的代码不起作用为我。我使用 DataSource 创建电子邮件附件(来自具有 inputStream 和 name 的对象),并且附件内容丢失。
看起来Stefan是对的,每次都必须返回一个新的inputStream。至少就我的具体情况而言。以下实现处理该问题:
bugs_'s code doesn't work for me. I use DataSource to create attachments to email (from objects that have inputStream and name) and content of attachments lost.
It looks like Stefan is right and a new inputStream must be returned every time. At least in my specific case. The following implementation deals with the problem:
当
InputStream
从DataSource
请求两次时,我遇到过这种情况:将日志处理程序与 MTOM 功能。使用这个代理流解决方案,我的实现工作正常:
I've met the situation when
InputStream
requested fromDataSource
twice: using a logging handler together with MTOM feature.With this proxy stream solution, my implementation works fine:
这是专门使用 Spring Boot org.springframework 的答案。 core.io.Resource 对象,我认为,我们很多人都是这样到达这里的。请注意,当我将 PNG 文件插入 HTML 格式的电子邮件时,您可能需要修改下面代码中的内容类型。
注意:正如其他人提到的,仅仅附加一个 InputStream 是不够的,因为它会被多次使用。只需映射到 Resource.getInputStream() 就可以了。
该类的用法如下所示:
Here is an answer for specifically working with the Spring Boot org.springframework.core.io.Resource object which is, I think, how a lot of us are getting here. Note that you might need to modify the content type in the code below as I'm inserting a PNG file into an HTML formatted email.
Note: As others have mentioned, merely attaching an InputStream isn't enough as it gets used multiple times. Just mapping through to Resource.getInputStream() does the trick.
Usage of the class looks like this:
。
。
。
。
。
。
可能的错误:元标记必须关闭。
<元>
.
.
.
.
.
.
possible error: the meta tag must be closed.
<meta></meta>