我正在尝试通过HTTP将(大(文件流式传输到数据库中。我使用 Tomcat 和 Jersey 作为 Webframework。我注意到,如果我将文件发布到我的资源,该文件首先在磁盘上缓冲(在 temp\MIME*.tmp} 中,然后再在我的 doPOST 方法中处理。
这确实是一种不希望的行为,因为它会使磁盘I/O翻倍,并且还会导致UX有些糟糕,因为如果浏览器已经完成上传,则用户需要等待几分钟(当然取决于文件大小(直到他获得HTTP响应。
我知道这可能不是大文件上传的最佳实现(因为你甚至没有任何恢复功能(,但要求也是如此。
所以我的问题是,是否有任何方法可以禁用多部分开机自检的(磁盘(缓冲。内存缓冲显然太贵了,但我真的不认为需要磁盘缓冲吗?(请解释(像YouTube这样的大型网站如何处理这种情况?或者,如果发送文件,是否至少有机会立即向用户提供反馈?(应该很糟糕,因为可能仍然有类似SQLException的东西(
如果有人仍然感兴趣,我通过使用Apache Commons Streaming api解决了同样的问题
该页面上的代码示例对我来说效果很好。
好的,所以经过几天的阅读和尝试不同的东西,我偶然发现了HTTPServletRequest。起初我什至不想尝试,因为它从@FormDataParam中带走了所有方便的方法,但由于我不知道还能做什么......
事实证明它有帮助。当我使用@Context HTTPServletRequest request
和request.getInputStream()
时,我根本没有磁盘缓冲。
现在我只需要弄清楚如何在没有@FormDataParam的情况下进入FormDataContentDisposition
。编辑:
多部分表单数据可能必须在磁盘上缓冲以解析请求的输入流。所以如果我想防止任何缓冲:(,似乎我必须自己手动解析它
最好的选择是完全控制并编写自己的servlet,它只抓取request.getInputStream(如果你正在使用文本,则为request.getWriter(并自己进行流式处理。大多数框架通过为您处理所有上传、临时存储等来使您的生活变得"轻松",并且通常会使诸如流式传输之类的事情变得困难。自己抓住流并做任何您想做的事情非常容易。
我很确定泽西岛正在将文件写入磁盘以确保内存不会被淹没。 由于您确切地知道需要如何处理传入的数据 ->流到数据库中,因此您可能必须编写自己的MessageBodyReader并让Jersey使用它来处理传入的多部分数据。