4

我正在尝试编写一个脚本,将一些数据块存储在平面 .txt 文件中(它们是小文件,少于 100 行)

无论如何,实际上,我正在尝试用该行的新值更新单个匹配行,同时将文件中的所有其他内容单独保留,但无法完全弄清楚如何仅修改 1 行而不是替换整个文件。

到目前为止,这是我的代码:

# get file contents as array.
array_of_lines = File.open( "textfile.txt", "r" ).readlines.map( &:chomp )

line_start = "123456:"    # unique identifier
new_string = "somestring" # a new string to be put after the line_start indentifier.

# cycle through array finding the one to be updated/replaced with a new line.
# the line we're looking for is in format 123456:some old value

# delete the line matching the line_start key
array_of_lines.delete_if( |line| line_start =~ line )

# write new string into the array.
array_of_lines.push( "#{line_start}:#{new_string}" )

# write array contents back to file, replacing all previous content in the process
File.open( "textfile.txt", "w" ) do |f|
    array_of_lines.each do |line|
        f.puts line
    end
end

内容将textfile.txt始终由以下格式组成:

unique_id:string_of_text

我可以在其中匹配unique_id脚本生成的使用应用程序数据,以确定要更新的文本行。

有没有更好的方法来做我想做的事情?

将整个文件读入内存似乎有点低效,循环遍历所有内容只是为了更新该文件中的一行。

4

1 回答 1

4

除非您正在写入的新数据与旧数据的长度相同,否则您无法做您想做的事情。

如果长度不同,则需要移动修改后文件中的所有字节。移动文件数据总是涉及重写所有内容(从修改点开始)。在这种情况下,您不妨重写整个文件,因为您的文件非常小。

如果替换数据的长度相同,则可以使用IO.seek将文件指针指向适当的位置,然后只需使用write输入替换数据即可。

如果您仍然不想重写整个文件,而只是移动数据(如果替换长度不同),那么您需要到seek正确的位置,然后write从该点开始到文件末尾。如果替换更短,您还需要调用File.truncate以调整文件大小。

于 2012-07-14T22:46:18.267 回答