run*_*ros 8 java io inputstream
InputStream类的JavaDoc说明如下:
将输入流中最多len个字节的数据读入一个字节数组.尝试读取len个字节,但可以读取较小的数字.实际读取的字节数以整数形式返回.此方法将阻塞,直到输入数据可用,检测到文件结尾或引发异常.
这也符合我的经验.例如,参见下面的示例代码:
Client:
Socket socket = new Socket("localhost", PORT);
OutputStream out = socket.getOutputStream();
byte[] b = { 0, 0 };
Thread.sleep(5000);
out.write(b);
Thread.sleep(5000);
out.write(b);
Server:
ServerSocket server = new ServerSocket(PORT);
Socket socket = server.accept();
InputStream in = socket.getInputStream();
byte[] buffer = new byte[4];
System.out.println(in.read(buffer));
System.out.println(in.read(buffer));
Output:
2 // Two bytes read five seconds after Client is started.
2 // Two bytes read ten seconds after Client is started.
Run Code Online (Sandbox Code Playgroud)
第一次调用read(缓冲区)阻塞,直到输入数据可用.但是,该方法在读取两个字节后返回,即使字节缓冲区中仍有空间,这与JavaDoc相对应,表明"尝试读取的数量为len个字节,但可以读取较小的数字 ".但是,当输入流来自套接字时,是否保证在读取至少一个字节的数据时该方法不会阻塞?
我问的原因是我在小型Java Web服务器NanoHTTPD中看到了以下代码,我想知道一个小于8k字节的HTTP请求(大多数请求都是)可以使线程无限制地阻塞,除非有保证它一旦读取某些数据,将不会阻止.
InputStream is = mySocket.getInputStream();
// Read the first 8192 bytes. The full header should fit in here.
byte[] buf = new byte[8192];
int rlen = is.read(buf, 0, bufsize);
Run Code Online (Sandbox Code Playgroud)
编辑:
让我尝试用相对类似的代码示例再次说明.EJP表示该方法会阻塞,直到EOS发出信号或者至少有一个字节的数据到达为止,在这种情况下,它会读取很多字节的数据,而不会再次阻塞,并返回该数字,这对应于方法的JavaDoc在InputStream类中读取(byte [],int,int).但是,如果实际查看源代码,很明显该方法确实会阻塞,直到缓冲区已满.我已经使用与上面相同的客户端测试了它,并将InputStream-code复制到我的服务器示例中的静态方法.
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(PORT);
Socket socket = server.accept();
InputStream in = socket.getInputStream();
byte[] buffer = new byte[4];
System.out.println(read(in, buffer, 0, buffer.length));
}
public static int read(InputStream in, byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
}
else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
}
else if (len == 0) {
return 0;
}
int c = in.read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len; i++) {
c = in.read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
}
catch (IOException ee) {
}
return i;
}
Run Code Online (Sandbox Code Playgroud)
此代码将作为其输出:
4 // Four bytes read ten seconds after Client is started.
Run Code Online (Sandbox Code Playgroud)
现在很明显,5秒后可以获得数据,但是该方法仍然阻止尝试填充整个缓冲区.Socket.getInputStream()返回的输入流似乎不是这种情况,但是一旦数据可用,它就会保证永远不会阻塞,就像JavaDoc说的那样但不像源代码所示?
但是,当输入流来自套接字时,是否保证在读取至少一个字节的数据时该方法不会阻塞?
我不认为这个问题意味着什么.该方法将阻塞,直到EOS被发信号通知或至少有一个字节的数据到达,在这种情况下,它会读取许多字节的数据,而不会再次阻塞,并返回该数字.
我在小型Java Web服务器NanoHTTPD中看到了以下代码
代码错了.它做出了无效的假设,即整个标题将在第一次读取时传递.我希望在这里看到一个循环,循环直到检测到空白行.
我想知道一个小于8k字节的HTTP请求(大多数请求都是)可以无限制地使线程阻塞,除非保证一旦读取一些数据它就不会阻塞.
我再也不认为这意味着什么.该方法将阻塞,直到至少一个字节到达,或EOS.期.
| 归档时间: |
|
| 查看次数: |
10327 次 |
| 最近记录: |