Как вставить строку в текстовый файл - PullRequest
10 голосов
/ 26 января 2010

У меня есть файл конфигурации, в который я хочу добавить строку, которая выглядит, например, вот так:

line1
line2
line3
line4

Новая строка не должна быть добавлена, но записана где-то в середине файла. Поэтому я ищу определенную позицию (или строку) в файле, и когда он был найден, я вставляю свою новую строку:

file = File.open(path,"r+")
while (!file.eof?)
  line = file.readline
  if (line.downcase.starts_with?("line1"))
    file.write("Some nice little sentence")
  end
end

Проблема в том, что Ruby перезаписывает строку в этой позиции новым текстом, поэтому получается следующее:

line1
Some nice little sentence
line3
line4

То, что я хочу, это "настоящая" вставка:

line1
Some nice little sentence
line2
line3
line4

Как этого достичь?

Ответы [ 4 ]

11 голосов
/ 26 января 2010

Если это небольшой файл, я думаю, что самый простой способ будет:

  • Прочитать файл полностью.
  • Вставить строку.
  • Написать новый файл.

Так Rails делает это за кадром.

Или вы можете скопировать его построчно, а затем переписать оригинал с помощью mv следующим образом:

require 'fileutils'

tempfile=File.open("file.tmp", 'w')
f=File.new("file.txt")
f.each do |line|
  tempfile<<line
  if line.downcase=~/^line2/
    tempfile << "Some nice little sentence\n"
  end
end
f.close
tempfile.close

FileUtils.mv("file.tmp", "file.txt")
6 голосов
/ 26 января 2010
def replace(filepath, regexp, *args, &block)
  content = File.read(filepath).gsub(regexp, *args, &block)
  File.open(filepath, 'wb') { |file| file.write(content) }
end


replace(my_file, /^line2/mi) { |match| "Some nice little sentence"}

line1
Some nice little sentence
line2
line3
line4

и если вы хотите добавить к существующему ...

replace(my_file, /^line2/mi) do |match| 
  "#{match} Some nice little sentence"
end

line1
line2 Some nice little sentence
line2
line3
line4
3 голосов
/ 26 января 2010

Пара других опций:

file = File.read(path).sub(/line2\n/, 'Some nice little sentence\n\1')
File.write(path, file)

file = File.readlines(path)
index = file.index("line2")
file.insert(index, "Some nice little sentence")
File.write(path, file)
0 голосов
/ 26 января 2010

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

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

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

Причина, по которой запись файла работает таким образом, заключается в том, что файл похож на массив байтов фиксированного размера: когда вы записываете байт в файл, вы перезаписываете существующий байт (я игнорирую случай, когда вы добавляете файл здесь). Таким образом, единственный способ вставить что-либо в файл - это сначала переместить старый контент в новое место, прочитав его из старого места и записав его в новое место. После этого вы можете «вставить» данные в свободную область.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...