Каковы все распространенные способы чтения файла в Ruby?

Каковы все распространенные способы чтения файла в Ruby?

Например, здесь приведен один метод:

fileObj = File.new($fileName, "r")
while (line = fileObj.gets)
  puts(line)
end
fileObj.close

Я знаю, что Ruby чрезвычайно гибкий. Каковы преимущества/недостатки каждого подхода?

Ответ 1

File.open("my/file/path", "r") do |f|
  f.each_line do |line|
    puts line
  end
end
# File is closed automatically at end of block

Можно также явно закрыть файл, как указано выше (передать блок в open), чтобы закрыть его для вас:

f = File.open("my/file/path", "r")
f.each_line do |line|
  puts line
end
f.close

Ответ 2

Самый простой способ, если файл не слишком длинный:

puts File.read(file_name)

Действительно, IO.read или File.read автоматически закрывает файл, поэтому нет необходимости использовать File.open с блоком.

Ответ 3

Будьте осторожны с файлами "slurping". Это, когда вы сразу читаете весь файл в памяти.

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

Поэтапный ввод-вывод выполняется очень быстро и почти всегда эффективнее, чем разрывы. Это на самом деле удивительно быстро.

Мне нравится использовать:

IO.foreach("testfile") {|x| print "GOT ", x }

или

File.foreach('testfile') {|x| print "GOT", x }

Наследует файл от IO, а foreach находится в IO, поэтому вы можете использовать либо.

У меня есть несколько тестов, показывающих влияние попыток чтения больших файлов с помощью read по сравнению с линейными вводами-выводами на " "Почему" и "вырезать" файл не хорошая практика?".

Ответ 4

Вы можете прочитать файл сразу:

content = File.readlines 'file.txt'
content.each_with_index{|line, i| puts "#{i+1}: #{line}"}

Когда файл большой или может быть большим, обычно лучше обрабатывать его по очереди:

File.foreach( 'file.txt' ) do |line|
  puts line
end

Иногда вам нужен доступ к дескриптору файла или управление чтением:

File.open( 'file.txt' ) do |f|
  loop do
    break if not line = f.gets
    puts "#{f.lineno}: #{line}"
  end
end

В случае двоичных файлов вы можете указать nil-separator и размер блока, например:

File.open('file.bin', 'rb') do |f|
  loop do
    break if not buf = f.gets(nil, 80)
    puts buf.unpack('H*')
  end
end

Наконец, вы можете сделать это без блока, например, при обработке нескольких файлов одновременно. В этом случае файл должен быть явно закрыт (улучшен в соответствии с комментарием @antinome):

begin
  f = File.open 'file.txt'
  while line = f.gets
    puts line
  end
ensure
  f.close
end

Ссылки: API файлов и IO API.

Ответ 5

Один простой метод - использовать readlines:

my_array = IO.readlines('filename.txt')

Каждая строка во входном файле будет представлять собой запись в массиве. Метод обрабатывает открытие и закрытие файла для вас.

Ответ 6

Я обычно делаю это:

open(path_in_string, &:read)

Это даст вам весь текст в виде строкового объекта. Он работает только под Ruby 1.9.

Ответ 8

вернуть последние n строк из файла your_file.log или .txt

path = File.join(Rails.root, 'your_folder','your_file.log')

last_100_lines = `tail -n 100 #{path}`