Версия для UNIX прямолинейна. Мы переводим терминал в режим прямого ввода (raw mode) и обычно одновременно отключаем эхо-контроль.

def getchar

 system('stty raw -echo') # Прямой ввод без эхо-контроля.

 char = STDIN.getc

 system('stty -raw echo') # Восстановить режим терминала.

 char

end

На платформе Windows придется написать расширение на С. Пока что альтернативой является использование одной из функций в библиотеке Win32API.

require 'Win32API'

def getchar

 char = Win32API.new('crtdll', '_getch', [], 'L').Call

end

Поведение в обоих случаях идентично.

10.1.21. Чтение всего файла в память

Чтобы прочитать весь файл в массив, не нужно даже его предварительно открывать. Все сделает метод IO.readlines: откроет файл, прочитает и закроет.

arr = IO.readlines('myfile')

lines = arr.size

puts 'myfile содержит #{lines} строк.'

longest = arr.collect {|x| x.length}.max

puts 'Самая длинная строка содержит #{longest} символов.'

Можно также воспользоваться методом IO.read (который возвращает одну большую строку, а не массив строк).

str = IO.read('myfile')

bytes = arr.size

puts 'myfile содержит #{bytes} байтов.'

longest=str.collect {|x| x.length}.max # строки - перечисляемые объекты!

puts 'Самая длинная строка содержит #{longest} символов.'

Поскольку класс IO является предком File, то можно вместо этого писать File.deadlines и File.read.

10.1.22. Построчное чтение из файла

Чтобы читать по одной строке из файла, можно обратиться к методу класса IO.foreach или к методу экземпляра each. В первом случае файл не нужно явно открывать.

# Напечатать все строки, содержащие слово 'target'.

IO.foreach('somefile') do |line|

 puts line if line =~ /target/

end

# Другой способ...

file = File.new('somefile')

file.each do |line|

 puts line if line =~ /target/

end

Отметим, что each_line — синоним each.

10.1.23. Побайтное чтение из файла

Для чтения из файла по одному байту служит метод экземпляра each_byte. Напомним, что он передает в блок символ (то есть целое число); воспользуйтесь методом chr, если хотите преобразовать его в «настоящий» символ.

file = File.new('myfile')

e_count = 0

file.each_byte do |byte|

 e_count += 1 if byte == ?e

end

10.1.24. Работа со строкой как с файлом

Иногда возникает необходимость рассматривать строку как файл. Что под этим понимается, зависит от конкретной задачи.

Объект определяется прежде всего своими методами. В следующем фрагменте показано, как к объекту source применяется итератор; на каждой итерации выводится одна строка. Можете ли вы что-нибудь сказать о типе объекта source, глядя на этот код?

source.each do |line|

 puts line

end

Это могли бы быть как файл, так и строка, содержащая внутри символы новой строки. В таких случаях строку можно трактовать как файл без всякого труда.

В последних версиях Ruby имеется также библиотека stringio.

Интерфейс класса StringIO практически такой же, как в первом издании этой книги. В нем есть метод доступа string, ссылающийся на содержимое самой строки.

require 'stringio'

ios = StringIO.new('abcdefghijkl ABC 123')

ios.seek(5)

ios.puts('xyz')

puts ios.tell        # 8

puts ios.string.dump # 'abcdexyzijkl ABC 123'

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату