Когда именно блокирует блоки ввода-вывода? - PullRequest
1 голос
/ 13 апреля 2019

InputStream.available () javadoc:

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

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

  2. Другое значение блокировки может заключаться в том, что если я хочу прочитать 3 байта и не иметь ни одного, или простоЕсли доступен 1 ​​байт, read() заблокирует и будет ждать появления большего количества байтов, но я не могу понять, что b / c, тогда вызов read() и попытка прочитать больше, чем доступно, могут вызвать вечную блокировку (просто чтение изображения 100байт из файла размером 10 байт).

В каком смысле java.io блокирует (1) или (2)?

Я не могу смоделировать ситуацию при чтенииметоды блока ввода-вывода (в смысле (2)) с FileInputStream или ByteArrayInputStream:

        // file content is: 1 2 3       
        FileInputStream myStream = new FileInputStream("d:\\file.txt");
        byte[] b = new byte[100];
        myStream.read(b);
        System.out.println("control reached here?");
        System.out.println(Arrays.toString(b));

Вывод:

reached here?
[122, 100, 122, 120, 118, 122, 120, 32, 118, 122, 120, 118, 32, 122, 120, 118, 32, 122, 118, 99, 122, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Второй вызов myStream.read(b) просто вернет -1 также без блокировки.

В каком сценарии происходит блокировка?

Я думал, что это происходит, если я пытаюсь прочитать 5 байтов, а есть три.Если его нет, это означает, что EOF / end-of-stream и -1 возвращается (без блокировки).

PS Я склонен думать, что java.io - это и (1), и (2).): это синхронно (1) и блокировка (2), но эта блокировка действительно наблюдается только при работе с сокетами (Socket.getInputStream() / Socket.getOutputStream()).

Ответы [ 2 ]

1 голос
/ 14 апреля 2019

Более или менее вариант 2, но вам не нужно беспокоиться о блокировке read, даже если некоторые данные уже обрабатываются.

Совет: не используйте available ().Это фактически бесполезно, информация, которую он предоставляет, на самом деле не позволяет вам делать то, что вы иначе не могли бы сделать.

Допустим, у вас есть сетевое соединение TCP.Пока вы или противоположная сторона не повесите соединение, нет ограничений на количество байтов, которые могут быть отправлены через линию, но, с другой стороны, возможно, что, скажем, осталось 10 байтов для чтения и больше не будетна некоторое время, потому что отправитель пока молчит.

Допустим, вы затем сделаете это:

byte[] b = new byte[100];
int r = in.read(b);

Что здесь произойдет, это то, что r будет 10, первые 10 слотов в вашем b будут заполнены, и это все.read 'smartly' возвращает: НЕ возвращает, если есть 0 байтов (чтение гарантирует, что оно заблокируется, пока не будет прочитано по крайней мере 1 байт или поток не будет закрыт, в этом случае он возвращает -1).... и если есть байты для чтения, он считывает эффективный кусок.

blocking, в частности, означает, что поток будет приостановлен и не возобновит работу, пока что-то не изменится.(поступают байты или поток закрывается).

0 голосов
/ 13 апреля 2019

Сценарий 2 - это значение.

(Обновлено после некоторых экспериментов)

Кажется, локальный дисковый ввод-вывод не считается блокирующим. Для FileInputStream метод available () возвращает оставшуюся длину файла. То есть, если файл имеет длину 91764 байта и вы прочитали 4 байта, после этого функция available () вернет 91760.

Я нахожу этот результат удивительным; ваш поток обязательно заблокирует дисковый ввод-вывод, если вы попытаетесь прочитать эти 91760 байт.

Результат более понятен для сетевых сокетов. Количество данных, которые могут поступить из удаленной системы в будущем, конечно, неизвестно; функция available () расскажет вам, сколько уже поступило, и теперь ее можно прочитать. В этом случае «блокировка» будет иметь неопределенную продолжительность - ожидание, пока удаленный хост не может отправить, что находится за пределами знаний системы ввода-вывода. на листьях 20 байтов доступны для дальнейшего чтения без блокировки.

...