Открываем файл и читаем содержимое в Ruby

open File read readline gets while each

Чтение файла это одна из наиболее важных задач в любом языке программирования. В Ruby это сделать очень просто.

examples/ruby/read_file.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

# 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

Related Pages

Упражнение: Анализ лог-файла Apache - считаем localhost
Анализ лога Apache - считаем запросы с localhost на Ruby

Author

Gabor Szabo (szabgab) Gabor Szabo