2010-01-26 75 views
10

我有一個配置文件,我想要添加一個字符串,像這樣:如何將字符串插入文本文件

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 

的問題是,紅寶石將覆蓋該位置的符合新的文本,所以結果如下:

line1 
Some nice little sentence 
line3 
line4 

我要的是一個「真正的」插入:

line1 
Some nice little sentence 
line2 
line3 
line4 

如何才能實現這一目標?

回答

11

如果它是一個小文件,我認爲最簡單的方法是:

  • 閱讀完整的文件。
  • 插入該行。
  • 寫入新文件。

那是幕後的方式Rails does it

或者你可以逐行復制它,然後覆蓋原來的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") 
0

最簡單的方法是讀取內存中的整個文件,然後將第一部分寫回文件,將插入的行寫入文件,然後將剩餘部分寫回文件。當您將文件作爲一行數組讀取時,這應該相對簡單,但如果文件非常大,則可能會遇到問題,因爲必須使用此方法將整個文件讀入內存。

或者,您可以找到要插入該行的位置,將該位置之後的行讀入內存,回溯到文件中的該位置,將新行寫入文件,最後寫入其餘行到文件。如果文件的其餘部分非常大,您將再次遇到問題,因爲您必須將其全部讀入內存。

第三種方法是將第一部分寫入新文件,將插入的行寫入新文件,將原始文件的剩餘部分寫入新文件,最後用新文件替換舊文件文件系統。這種方法允許您一次處理一行文件,因此您可以處理不適合內存的文件。

文件寫入這樣工作的原因是因爲文件就像是一個固定大小的字節數組:當您向該文件寫入一個字節時,您將覆蓋現有字節(我忽略了追加到一個文件在這裏)。因此,將任何內容插入文件的唯一方法是首先將舊內容從舊位置讀取並將其寫入新位置,以將舊內容移至新位置。之後,您可以將數據「插入」現在空置的區域。

4

一對夫婦的其他選項:

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

我試圖使用這個,但'File.write(path,'w')'用單個字符'w'覆蓋文件 - 什麼是正確的方法? – dgmstuart 2013-09-10 22:25:12

7
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 
+0

我確信你注意到你在最後一個例子中打印了line2兩次。 – Magne 2014-05-19 18:44:32

相關問題