0

我以简单的方式编写了下载文件:

@ResourceMapping(value = "content")
public void download(ResourceRequest request, ResourceResponse response) {
//...
SerializableInputStream serializableInputStream = someService.getSerializableInputStream(id_of_some_file);

response.addProperty(HttpHeaders.CACHE_CONTROL, "max-age=3600, must-revalidate");
response.setContentType(contentType);
response.addProperty(HttpHeaders.CONTENT_TYPE, contentType);
response.addProperty(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''"
    + URLEncoder.encode(fileName, "UTF-8"));

OutputStream outputStream = response.getPortletOutputStream();
byte[] parcel = new byte[4096];

while (serializableInputStream.read(parcel) > 0)
    outputStream.write(parcel);

outputStream.flush();
serializableInputStream.close();
outputStream.close();
//...
}

SerializableInputStream此处描述了- JavaDocs。它允许对 InputStream 进行序列化,例如,通过远程处理传递。

我从输入读取并将其写入输出,而不是一次写入所有字节。但不幸的是,portlet 并没有“流式传输”内容——文件(例如图像)只有在读取整个输入流之后才会发送到浏览器——这就是它的样子。我看到从数据库(从实时日志)中读取的文件,但我没有在屏幕上看到任何“增长”的图像。

我究竟做错了什么?是否可以在 Liferay 6.0.6 和 Spring Portlet MVC 中真正流式传输文件?

4

1 回答 1

0

你在哪里做这个?我担心你这样做而不是渲染你的 portlet 的 HTML(例如渲染阶段)。通常,portlet 内容嵌入在 HTML 页面中,因此您需要资源阶段,它(大致)表现得像一个 servlet。

此外,您提供的代码与您提出的实际问题不匹配:您使用评论//read from input stream (file), write file to os并询问如何做不同的事情,以便在内存中没有完整的内容。

由于评论在内存中没有任何内容,您可以在写入输出流时循环读取输入文件:潜在的问题是什么?您是否在门户环境中实现下载流式传输时遇到问题,或者在写入流时从文件中读取数据有困难(即使用太多内存)?

编辑:感谢您的澄清。您是否尝试过更早地刷新流?您可以随时执行此操作 - 例如每个循环(尽管这可能有点过多)。另外,请记住,浏览器以及文件本身必须以您期望的方式处理它:如果图像没有“增量”编码,浏览器可能不会以这种方式显示它。

您是否也尝试过处理大文件?可能是因为您的文件太小而无法触发自动刷新...

另外,我认为这filename*=UTF-8''看起来很奇怪。可能是有效的编码,但我从未见过这个

于 2012-07-25T06:52:23.360 回答