Чтение файла это одна из наиболее важных задач в любом языке программирования. В Ruby это сделать очень просто.
if ARGV.length != 1
puts "We need exactly one parameter. The name of a file."
exit;
end
filename = ARGV[0]
puts "Going to open '#{filename}'"
fh = open filename
# puts fh
content = fh.read
fh.close
puts content
ruby read_file.rb some/file.txt
Программа ожидает от нас передачи имени файла в командной строки и затем использует ARGV для доступа к значениям. Вообще-то, сначала мы проверяем, передал ли пользователь нужное количество аргументов, и прерываем работу, если это не так.
Затем мы используем вызов open
для открытия файла на чтение. Этот вызов вернем нам объект класса File.
(Если мы выведем содержимое fh
, то получим что-то вроде #<File:0x007f8c0310f748>
)
Метод read
этого класса прочитает все содержимое файла, которое мы сохраняем в переменную content
.
Это полное содержимое файла, включая переводы строк.
По сути это тоже самое, что и slurp в Perl
Читаем файл построчно
Чтение всего файла одним оператором выглядит простым, но не всегда хорошая идея. Например, если у вас файл лога размером в 10 Gb, то вероятно, вам не захочется считать его весь в память. Всегда ли у вас есть 10 Gb свободной памяти?
В таком случае, будет лучше читать файл построчно. После чтения строки, делайте с этой строкой что вам нужно, а затем заменяйте на новую строку. Таким образом, в каждый момент времени в памяти мы держим только одну строку. Намного эффективнее.
Есть два способа реализовать это, и я не уверен, есть ли какие-то преимущества или недостатки в каждом их них.
Первый - с помощью gets
и while
. Выглядит будто это написал кто-то из мира Perl 5:
examples/ruby/read_file_by_line_while.rb
if ARGV.length != 1
puts "We need exactly one parameter. The name of a file."
exit;
end
filename = ARGV[0]
puts "Going to open '#{filename}'"
fh = open filename
while (line = fh.gets)
puts line
end
fh.close
Другой способ - с помощью each
. Выглядит более Rubyish:
examples/ruby/read_file_by_line_each.rb
if ARGV.length != 1
puts "We need exactly one parameter. The name of a file."
exit;
end
filename = ARGV[0]
puts "Going to open '#{filename}'"
fh = open filename
fh.each do |line|
puts line
end
fh.close