Что делает InputStream. available() в Java?

Что InputStream.available() делает в Java? Я читал документацию, но до сих пор не могу разобраться.

Док говорит:

Возвращает количество байтов, которые могут быть прочитаны (или пропущены) из этого входного потока без блокировки следующей вызывающей стороной метода для этого входного потока. Следующим вызывающим может быть тот же поток или другой поток.

Доступный метод для класса InputStream всегда возвращает 0.

Что они имеют в виду под блокировкой? Означает ли это просто синхронизированный вызов?

И самое главное, какова цель метода available()?


person Albus Dumbledore    schedule 12.09.2010    source источник
comment
Существует очень мало действительно полезных способов использования available(). Один из них предназначен для чтения из System in.   -  person user207421    schedule 13.09.2010


Ответы (2)


Блокировка здесь не связана с многопоточностью или синхронизацией. Вместо этого он относится к блокировке ввода-вывода (см. это для получения дополнительной информации). Если вы отправляете запрос на чтение, а канал недоступен, блокирующий вызов будет ждать (или блокировать), пока данные не будут доступны (или канал будет закрыт, выдаст исключение и т. д.).

Так зачем использовать available() ? Таким образом, вы можете определить, сколько байтов читать, или определить, собираетесь ли вы блокировать.

Обратите внимание, что Java также имеет возможности неблокирующего ввода-вывода. См. здесь для более подробной информации

person Brian Agnew    schedule 12.09.2010
comment
Я наткнулся на этот вопрос, и теперь мне интересно, могу ли я использовать available() для решения своей проблемы, не прибегая к NIO. Мой вопрос: stackoverflow.com/questions/3867042/ - person Bart van Heukelom; 06.10.2010
comment
Этот ответ неверен. Блокирующий вызов будет заблокирован, пока нет доступных данных. Если вы попросите четыре, а их будет три, вы получите три. - person user207421; 21.06.2013

В InputStreams вызовы read() называются "блокирующими" вызовы методов. Это означает, что если данные недоступны во время вызова метода, метод будет ждать, пока данные станут доступными.

Метод available() сообщает вам, сколько байтов можно прочитать, пока вызов read() не заблокирует поток выполнения вашей программы. В большинстве входных потоков все вызовы read() блокируются, поэтому по умолчанию available возвращает 0.

Однако в некоторых потоках (таких как BufferedInputStream, у которых есть внутренний буфер) некоторые байты считываются и хранятся в памяти, поэтому вы можете прочитать их, не блокируя выполнение программы. В этом случае метод available() сообщает вам, сколько байт хранится в буфере.

person Vivien Barousse    schedule 12.09.2010
comment
BufferedInputStream. available() сообщает вам, сколько байтов можно прочитать без блокировки. Это сумма количества байтов, уже находящихся в буфере, и результата avaiable() вложенного входного потока. Также обратите внимание, что available() всегда возвращает ноль для сокета SSL. - person user207421; 13.09.2010
comment
Чего я не совсем понял, так это того, какая польза от этого знания. Я действительно не понимаю, почему меня это должно волновать, то есть я не вижу, где и когда в приложении mu я мог бы найти ему какое-то применение. Конечно, довольно очевидно, что я невежественен, но это из-за моего недостатка опыта. - person Albus Dumbledore; 13.09.2010
comment
Как я уже сказал выше, полезных применений очень мало. Вы должны знать, что имеете дело с потоком, который даст ненулевой ответ, а затем вам нужно использовать результат. - person user207421; 13.09.2010
comment
Не могли бы вы объяснить, что вы подразумеваете под если данные недоступны во время вызова метода, метод будет ждать, пока данные станут доступными? Скажем, у меня есть файл без содержимого. Если я вызову это в FileInputStream, будет ли он вечно ждать поступления данных из файла? Означает ли это, что все, что последовало за вызовом потока в исходном коде, будет приостановлено на неопределенный срок? - person SexyBeast; 10.01.2013
comment
@Cupidvogel: Нет, для файла без содержимого поток немедленно вернет -1, чтобы указать, что данных нет. Однако если у вас есть сетевойпоток, где другой конец соединения держит его открытым, но не отправляет никаких данных, тогда это действительно заблокируется навсегда. - person Jon Skeet; 15.01.2013
comment
Спасибо. Что подразумевается под блокировкой потока выполнения? А также, что подразумевается под В большинстве входных потоков все вызовы read() блокируются, поэтому по умолчанию available возвращает 0.? - person SexyBeast; 15.01.2013
comment
Блокировка потока выполнения означает, что функция не вернется до тех пор, пока следующий байт не будет получен из источника ввода (например, с диска, из Интернета). Вы должны учитывать, что большинство реализаций входных потоков извлекают по одному байту за раз. Если это неприемлемо (а так оно и есть), оберните его в BufferedInputStream. - person Michael Deardeuff; 15.01.2013
comment
Во всех входных потоках чтение блокируется, и это не объясняет, почему available() по умолчанию возвращает ноль. Существует много случаев, когда потоки могут возвращать ненулевые значения, а не только буферизованные, которые известны локально: потоки ввода сокетов, потоки ввода файлов, потоки ввода HttpURLConnection, ... - person user207421; 29.04.2017