使用Jersey流媒体视频文件表格GridFS?

时间:2016-01-28 17:22:17

标签: java mongodb jersey streaming gridfs

嘿所以我有以下代码,客户端应用程序使用它来播放存储在MongoDB中的视频文件(使用GridFS)。

我的问题是代码是否必须等到组成视频文件的每个字节都写入流中,然后才将响应发送回客户端?

显然,如果是这种情况,那将是非常不受欢迎的,因为这会占用内存中的所有字节,这意味着大文件可能会导致服务器崩溃。流式传输的目的是避免将所有字节消耗到内存中。

@Path("video/{videoId}")    
@GET                        
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getTheSelectedVideo(@PathParam("videoId") String videoId){

     GridFSDBFile videoFile = gridFS.findOne(new ObjectId(videoId));

     ByteArrayOutputStream baos = new ByteArrayOutputStream();

    try {
        return Response.ok(videoFile.writeTo(baos)).build();
    } 
    catch (IOException e) {
        e.printStackTrace();
        return Response.serverError().build();
    }

}

注意这里的gridFS是指在代码中进一步创建的GridFS对象。

任何有关清除此功能的帮助都会很棒!感谢。

1 个答案:

答案 0 :(得分:0)

您可以使用StreamingOutput来流式传输输出。例如

@Path("video/{videoId}")    
@GET                        
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getTheSelectedVideo(@PathParam("videoId") String videoId){

    final GridFSDBFile videoFile = gridFS.findOne(new ObjectId(videoId));

    StreamingOutput entity = new StreamingOutput() {
        @Override
        public void write(OutputStream output) 
                throws IOException, WebApplicationException {
            InputStream in = videoFile.getInputStream();
            ReaderWriter.writeTo(in, output);
        }   
    };
    return Response.ok(entity).build();
}

ReaderWriter只是一个OP助手。但StreamingOutput的作用是允许您直接写入响应输出流。默认缓冲区大小为8192字节。如果要将其更改为较低的值,可以设置this property,但这会影响整个应用程序。如果你想做的话,请务必阅读javadoc以获取所有细节。