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代码。 这就是我所相信的。