如何获得InputStream的大小?

时间:2016-02-19 09:15:00

标签: java inputstream content-length

我从InputStream获得了ProcessBuilder,可以实际读取stdout信息流。

问题:如何知道该内存InputStream的大小,以便将其写入HttpResponse http标头?

InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

OutputStream out = response.getOutputStream();
int bytes;
while ((bytes = br.read()) != -1) {
    out.write(bytes);
}

//how can I know the size of the inmemory stream/file written?
//response.setContentLength((int) pdfFile.length());

5 个答案:

答案 0 :(得分:4)

没有输入流的大小。考虑一个永不退出的程序,或者一个永不停止发送的套接字对等体。而且您无需知道将其写入HttpResponse标头。 Content-length会自动为您管理。

答案 1 :(得分:2)

如果你真的想设置内容长度标题,你需要在写入响应OutputStream之前读取整个流

ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int count;
while ((count = in.read(bytes)) > 0) {
    out.write(bytes, 0, count);
}
response.setContentLength(out.size();
out.writeTo(response.getOutputStream());

注意:使用这种方法,您现在已将整个流读入内存,这将对可用内存产生影响,并且可能无法很好地扩展。

答案 2 :(得分:2)

试试这个

    InputStream is = process.getInputStream();
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    int b;
    while ((b = is.read()) != -1)
        os.write(b);
    response.setContentLength(os.size());
    response.getOutputStream().write(os.toByteArray());

答案 3 :(得分:1)

InputStream本身并没有大小。可以想象,它永远可以继续提供字节。或者生产端可以在没有警告的情况下结束流。

如果你必须找出长度,那么你必须读到最后,计算字节数,并在完成时报告长度。

您对HTTP的Content-length标题感到担忧,而且您已经明白了。事实是,HTTP的原始版本不是为大型动态生成的内容而设计的。协议固有地希望您在开始编写内容之前知道内容的大小 - 但如果它(例如)正在进行的聊天或摄像机的输出,那该怎么可能?

解决方案是HTTP' chunked transfer encoding。在这里,您不需要设置Content-Length标头。您设置Transfer-Encoding: chunked,然后将内容写为块,每个块都有一个大小标题。

HTTP RFC有一个详细信息,或https://en.wikipedia.org/wiki/Chunked_transfer_encoding稍微友好。

但是,大多数HTTP API会向您隐藏此详细信息。除非您从头开始创建Web库(可能是出于学术原因),否则您不必考虑Content-LengthTransfer-Encoding

答案 4 :(得分:0)

import org.apache.commons.io.IOUtils;

   byte[] bytes = IOUtils.toByteArray(inputStream);
   log.message("bytes .lenght "+bytes.length);

            if (bytes.length > 400000)
//some byte range limit`enter code  can add any byte range
              {
                throw new Exception("File Size is larger than 40 MB ..");
              }