Java 如何获取 InputStream 的大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35501489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get the size of an InputStream?
提问by membersound
I'm having an InputStream
from a ProcessBuilder
that acutally reads the stdout
stream.
我有一个InputStream
来自ProcessBuilder
acutally 读取stdout
流。
Question: how can I know the size of that inmemory InputStream
, so I can write it to a HttpResponse
http header?
问题:我如何知道 inmemory 的大小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());
回答by user207421
There is no such thing as the size of an input stream. Consider a program which never exits, or a socket peer which never stops sending. And you don't need to know to write it to an HttpResponse
header. The Content-length
is managed automatically for you.
没有输入流的大小之类的东西。考虑一个永不退出的程序,或者一个永不停止发送的套接字对等体。而且您不需要知道将其写入HttpResponse
标头。将Content-length
自动为您进行管理。
回答by lance-java
If you really want to set the content length header, you'll need to read the entire stream before writing to the response OutputStream
如果您真的想设置内容长度标头,则需要在写入响应 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());
Note: With this approach you've now read the entire stream into memory, this will have an impact on available memory and likely won't scale well.
注意:使用这种方法,您现在已将整个流读入内存,这将对可用内存产生影响,并且可能无法很好地扩展。
回答by saka1029
Try this
尝试这个
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());
回答by slim
An InputStream
inherently doesn't have a size. It could conceivably keep delivering bytes forever. Or the producing end could end the stream without warning.
AnInputStream
本质上没有大小。可以想象,它可以永远保持传送字节。或者生产端可以在没有警告的情况下结束流。
If you must find out the length, then you have to read to the end, counting the bytes, and report the length when you finish.
如果你必须找出长度,那么你必须读到最后,计算字节数,并在完成时报告长度。
You're worrying about HTTP's Content-length
header, and you've got a point. The fact is that the original version of HTTP was not designed for large, dynamically generated content. The protocol inherently expects you to know the size of the content before you start writing it - yet how is that possible if it's (for example) an ongoing chat, or the output of a video camera?
您正在担心 HTTP 的Content-length
标头,您说得对。事实上,HTTP 的原始版本并不是为大型动态生成的内容而设计的。该协议固有地希望您在开始编写内容之前知道内容的大小 - 但如果它是(例如)正在进行的聊天或摄像机的输出,那怎么可能呢?
The solution is HTTP's chunked transfer encoding
. Here you don't set a Content-Length
header. You set Transfer-Encoding: chunked
, then write the content as chunks, each of which has a size header.
解决方案是 HTTP 的chunked transfer encoding
. 在这里你没有设置Content-Length
标题。您设置Transfer-Encoding: chunked
,然后将内容写为块,每个块都有一个大小标头。
The HTTP RFC has details one this, or https://en.wikipedia.org/wiki/Chunked_transfer_encodingis slightly more friendly.
HTTP RFC 对此有详细说明,或者https://en.wikipedia.org/wiki/Chunked_transfer_encoding稍微友好一些。
However most HTTP APIs hide this detail from you. Unless you are developing a web library from scratch (perhaps for academic reasons), you shouldn't have to think about Content-Length
or Transfer-Encoding
.
然而,大多数 HTTP API 对你隐藏了这个细节。除非您是从头开始开发 Web 库(可能出于学术原因),否则您不必考虑Content-Length
或Transfer-Encoding
。
回答by Ravinath Edirisinghe
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 ..");
}