FileUtils.install("foo.so","/usr/lib")
# Существующий файл foo.so не будет переписан,
# если он не отличается от нового.
Дополнительную информацию о модуле FileUtils
см. на сайте ruby-doc.org или в любом другом справочном руководстве.
10.1.20. Ввод символов с клавиатуры
В данном случае мы имеем в виду небуферизованный ввод, когда символ обрабатывается сразу после нажатия клавиши, не дожидаясь, пока будет введена вся строка.
Это можно сделать и в UNIX, и в Windows, но, к сожалению, совершенно по-разному.
Версия для 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\nABC\n123")
ios.seek(5)
ios.puts("xyz")
puts ios.tell # 8
puts ios.string.dump # "abcdexyzijkl\nABC\n123"
с = ios.getc
puts "с = #{c}" # с = 105
ios.ungetc(?w)
puts ios.string.dump # "abcdexyzwjkl\nABC\n123"
puts "Ptr = #{ios.tell}"
s1 = ios.gets # "wjkl"
s2 = ios.gets # "ABC"
10.1.25. Чтение данных, встроенных в текст программы
Когда подростком вы учили язык BASIC, копируя программы из журналов, то, наверное, для удобства часто пользовались предложением DATA
. Оно позволяло включать информацию прямо в текст программы, но читать ее так, будто она поступает из внешнего источника.
При желании то же самое можно сделать и в Ruby. Директива __END__
в конце программы говорит, что дальше идут встроенные данные. Их можно читать из глобальной константы DATA
, которая представляет собой обычный объект IO
. (Отметим, что маркер __END__
должен располагаться с начала строки.)
Читать дальше
Конец ознакомительного отрывка
Купить книгу