Write an InputStream to an HttpServletResponse

前端 未结 3 1450
一个人的身影
一个人的身影 2020-12-03 07:02

I have an InputStream that I want written to a HttpServletResponse. There\'s this approach, which takes too long due to the use of byte[]

InputStream is = ge         


        
3条回答
  •  被撕碎了的回忆
    2020-12-03 07:46

    Just write in blocks instead of copying it entirely into Java's memory first. The below basic example writes it in blocks of 10KB. This way you end up with a consistent memory usage of only 10KB instead of the complete content length. Also the enduser will start getting parts of the content much sooner.

    response.setContentLength(getContentLength());
    byte[] buffer = new byte[10240];
    
    try (
        InputStream input = getInputStream();
        OutputStream output = response.getOutputStream();
    ) {
        for (int length = 0; (length = input.read(buffer)) > 0;) {
            output.write(buffer, 0, length);
        }
    }
    

    As creme de la creme with regard to performance, you could use NIO Channels and a directly allocated ByteBuffer. Create the following utility/helper method in some custom utility class, e.g. Utils:

    public static long stream(InputStream input, OutputStream output) throws IOException {
        try (
            ReadableByteChannel inputChannel = Channels.newChannel(input);
            WritableByteChannel outputChannel = Channels.newChannel(output);
        ) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
            long size = 0;
    
            while (inputChannel.read(buffer) != -1) {
                buffer.flip();
                size += outputChannel.write(buffer);
                buffer.clear();
            }
    
            return size;
        }
    }
    

    Which you then use as below:

    response.setContentLength(getContentLength());
    Utils.stream(getInputStream(), response.getOutputStream());
    

提交回复
热议问题