InputStream.available()在Java中做什么?
InputStream.available()
在Java中做什么? 我阅读了文档,但是我仍然无法解决。
该文件说:
返回可以从此inputstream读取(或跳过)的字节数,而不会被此inputstream的下一个调用者方法阻塞。 下一个调用者可能是相同的线程或另一个线程。
类InputStream的可用方法始终返回0。
他们是什么意思的阻止 ? 这是否意味着同步通话?
最重要的是, available()
方法的目的是什么?
阻塞与这里的线程或同步无关。 相反,它涉及到阻止IO(更多信息见这个 )。 如果您发出读取请求,且通道没有可用通道,阻塞呼叫将等待(或阻止),直到数据可用(或通道closures,引发exception等)
那么为什么使用available()
呢? 因此,您可以确定要读取多less个字节,或者确定是否要阻止。
请注意,Java也具有非阻塞IOfunction。 在这里看到更多的细节
在InputStream中, read()
调用被称为“阻塞”方法调用。 这意味着如果在方法调用时没有数据可用,该方法将等待数据可用。
available()
方法告诉你可以读取多less个字节,直到read()
调用将阻塞程序的执行stream程。 在大多数inputstream中,所有对read()
调用都被阻塞,这就是默认情况下返回0的原因。
但是,在某些stream(如BufferedInputStream
,有内部缓冲区),一些字节被读取并保存在内存中,所以您可以读取它们而不阻塞程序stream。 在这种情况下, available()
方法告诉你在缓冲区中保留了多less个字节。
考虑如果你写的软件非常坏..你写一个操作系统。
这个操作系统除其他外还有键盘input。
所以你问你的操作系统去获得一些键盘input,但没有按键,没有在缓冲区中。 您的整个操作系统将然后吊死,直到它得到一个键盘input。
与“向前看”对比,你会问在调用之前KB是否有任何字符。 你得到答案否,所以你的操作系统然后去做别的。
这就是为什么你应该关心,现在如果你把这个问题乘以每一个潜在的阻碍任务,你就会明白为什么“向前看”是至关重要的。
因为它也适用于OUTPUT:磁盘驱动器接口的内存也可以将数据驱动到磁盘驱动器,而不是将其处理。 如果您不知道驱动器缓冲区是否充斥着数据,则该任务将阻塞,直到缓冲区可以接受更多的数据。
这也突出了“有用的东西很less”的废话。
available()
一个可能的实际用法是使用它来select一个合理的缓冲区长度。
static final int LEN = 4096; long copy(InputStream in, OutputStream out) throws IOException { int count = 0L; int avl = in.available(); if (avl == 0) { // 0 returned without IOException? possibly mean eof? return 0L; } //byte[] buf = new byte[avl == 0 ? LEN : Math.min(avl, LEN)]; byte[] buf = new byte[Math.min(avl, LEN)]; for (int len; (len = in.read(buf)) != -1; count+= len) { out.write(buf, 0, len); } return count; }
该文件说,
返回:估计可以从此inputstream读取(或跳过)的字节数,不阻塞
0
如果达到inputstream的末尾,则为0
。
和
如果此inputstream已通过调用
close()
方法closures,则该方法的子类的实现可能会select抛出IOException
。
UPDATE
我已经知道这个想法不被推荐。 我甚至在JDK doc警告之前就已经知道这个风险了。 (我曾尝试从available
的几个GB大小的FileInputStream
分配一个缓冲区。)
JDK8 / InputStream的#可用
使用这个方法的返回值来分配一个缓冲区来保存这个stream中的所有数据是绝对正确的。
JDK5 / InputStream的#速效
但是,在编程中,不应该有或者always wrong
代码。 这就是我所相信的。