7

我正在尝试通过 HTTP 将(大)文件流式传输到数据库中。我使用 Tomcat 和 Jersey 作为 Web 框架。我注意到,如果我 POST 一个文件到我的资源,该文件首先在磁盘上缓冲(在 temp\MIME*.tmp} 中,然后在我的 doPOST 方法中处理它。

这确实是一种不受欢迎的行为,因为它使磁盘 I/O 加倍,并且还导致了一些糟糕的 UX,因为如果浏览器已经完成上传,用户需要等待几分钟(当然取决于文件大小)直到他得到HTTP 响应。

我知道这可能不是大文件上传的最佳实现(因为您甚至没有任何恢复功能),但要求也是如此。:/

所以我的问题是,是否有任何方法可以禁用 MULTIPART POST 的(磁盘)缓冲。内存缓冲显然太贵了,但我真的不认为需要磁盘缓冲吗?(请解释)像 YouTube 这样的大型网站如何处理这种情况?或者如果文件被发送,至少有机会给用户即时反馈?(应该是坏的,因为可能仍然有类似 SQLException 的东西)

4

4 回答 4

4

好的,所以经过几天的阅读和尝试不同的东西后,我偶然发现了 HTTPServletRequest。起初我什至不想尝试,因为它带走了@FormDataParam 的所有便利方法,但因为我不知道还能做什么......

事实证明它有帮助。当我使用时 @Context HTTPServletRequest requestrequest.getInputStream()我根本没有得到磁盘缓冲。

现在我只需要弄清楚如何在没有@FormDataParam 的情况下到达 FormDataContentDisposition

编辑:

行。MultiPartFormData 可能必须在磁盘上缓冲以解析请求的 InputStream。所以看来我必须自己手动解析它,如果我想防止任何缓冲:(

于 2012-05-22T10:10:26.937 回答
4

如果有人仍然感兴趣,我通过使用Apache Commons Streaming api解决了同样的问题

该页面上的代码示例对我来说效果很好。

于 2013-11-15T23:55:43.343 回答
3

我很确定 Jersey 正在将文件写入磁盘以确保内存不会被淹没。由于您确切知道需要对传入数据做什么 -> 流入数据库,因此您可能必须编写自己的 MessageBodyReader 并让 Jersey 使用它来处理传入的多部分数据。

于 2012-05-16T10:33:31.167 回答
3

您最好的选择是完全控制并编写您自己的 servlet,它只获取 request.getInputStream(或 request.getWriter,如果您正在使用文本)并自己进行流式传输。大多数框架通过为您处理所有上传、临时存储等,使您的生活“轻松”,并且通常使您难以进行流式传输等事情。自己抓住流并做任何你想做的事情是很容易的。

于 2012-05-22T15:22:19.970 回答