问题描述
我正在读取通过网络上传的文件,它通过 http 发送,我们通过 BufferedInputStream 接收。有时我们会在读取流的过程中遇到超时异常。我的工作理论是在我们可以处理整个文件之前从客户端关闭连接。文件的顺序是mb。
这个理论有意义吗?客户端是否需要保持连接打开才能让服务器从输入流中完全读取字节?
解决方法
这种情况下没有好消息,数据会丢失。
,这个理论有意义吗?客户端是否需要保持连接打开才能让服务器从输入流中完全读取字节?
没有
只要 BufferedInputStream
在缓冲区中有字节,任何对 read()
/ read(byte[])
/ read(byte[],int,int)
的调用都会简单地从缓冲区中获取数据,并且永远不会触摸底层输入流。
只要你不触碰所述输入流,它就不会开始在晴朗的天空中抛出异常。您需要在实际的套接字输入流上调用 something(读取、关闭、刷新、写入等),以便抛出异常。
可能发生的是混合模式操作:您调用例如:
var raw = socket.getInputStream();
var buffered = new BufferedInputStream(raw);
byte[] b = new byte[1000];
buffered.read(b); // actually reads 4000 bytes into buffer,giving 1000 of them.
// 3000 left in the buffer!
byte[] c = new byte[2000];
buffered.read(c); // works fine and never touches raw. Can't throw.
byte[] d = new byte[2000];
buffered.read(d); // 'mixed mode'
这里,在“混合模式”的情况下,前1000个字节由缓冲区填充,然后调用raw.available()
(来源:BufferedInputStream.java的实际源代码);如果它返回一个非零数字,则直接从 raw 中获取更多数据;如果是 0,则 read()
只返回(read()
没有义务读取所有请求的字节;它只需要 [A] 读取至少 1,并且 [B] 返回它做了多少阅读;通常你想要readNBytes
)。
但是,允许 in.available()
抛出。如果是这样,瞧。
但是,正常的 TCP 关闭不会导致 TimeoutExceptions。
更可能的情况如下:您的代码处理数据的速度不够快。发送实体在某个时候只是受够了这一切,拒绝继续让您占用文件句柄并挂断您的电话。如果您已经在使用缓冲区,则可能中间有一些网络设备很慢,或者服务器配置了对您的网络连接速度的不切实际的期望。