Книга: Программирование на языке Ruby

10.1.8. Буферизованный и небуферизованный ввод/вывод

10.1.8. Буферизованный и небуферизованный ввод/вывод

В некоторых случаях Ruby осуществляет буферизацию самостоятельно. Рассмотрим следующий фрагмент:

print "Привет... "
sleep 10
print "Пока!n"

Если запустить эту программу, то вы увидите, что сообщения «Привет» и «Пока» появляются одновременно, после завершения sleep. При этом первое сообщение не завершается символом новой строки.

Это можно исправить, вызвав метод flush для опустошения буфера вывода. В данном случае вывод идет в поток $defout (подразумеваемый по умолчанию для всех методов Kernel, которые занимаются выводом). И поведение оказывается ожидаемым, то есть первое сообщение появляется раньше второго.

print "Привет... "
STDOUT.flush
sleep 10
print "Пока!n"

Буферизацию можно отключить (или включить) методом sync=, а метод sync позволяет узнать текущее состояние.

buf_flag = $defout.sync # true
STDOUT.sync = false
buf_flag = STDOUT.sync  # false

Есть еще по крайней мере один низкий уровень буферизации, который не виден. Если метод getc возвращает символ и продвигает вперед указатель файла или потока, то метод ungetc возвращает символ назад в поток.

ch = mystream.getc # ?А
mystream.ungetc(?C)
ch = mystream.getc # ?C

Тут следует иметь в виду три вещи. Во-первых, только что упомянутая буферизация не имеет отношения к механизму буферизации, о котором мы говорили выше в этом разделе. Иными словами, предложение sync=false не отключает ее. Во-вторых, вернуть в поток можно только один символ; при попытке вызвать метод ungetc несколько раз будет возвращен только символ, прочитанный последним. И, в-третьих, метод ungetc не работает для принципиально небуферизуемых операций (например, sysread).

Оглавление книги

Оглавление статьи/книги

Генерация: 1.849. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз