我有一个用Ruby编写的命令行日志应用程序。我希望能够回溯新条目,并按时间顺序将条目写入文件。这些是多行条目,因此事后的简单排序是不够的。我知道如何在文本文件的末尾添加一行:
def write(file, entry)
open(file, 'r+') do |f|
f.write entry
end
end
但是,我们假设我有一个名为line_number
的变量,其中包含我想要开始写入的位置。是否有一种简单的方法可以将entry
写入file
,从行号line_number
开始,同时保留原始内容?
例如,给定一个包含内容的文件:
a
c
对方法write_at(file, 2, 'b')
的调用应该产生:
a
b
c
答案 0 :(得分:1)
The main problem in doing this, if you are unable to load the entire file into memory, is that text files are sequential files that can be modified only at the end, as opposed to binary files that can be modified at any position in the file. If you could store the data in such a way that you could guarantee that all records would have equal byte lengths, then you could find the desired position and effectively shift everything after it by one record, and insert the desired record. Thus you would only have to rewrite part of the file. This is not commonly done these days, but it's possible.
If you were to use this binary storage format, then you could have a separate thing that formats it into log lines.
Even better would be to use a data base like SQLite; this would do the insertion and shifting for you (using a 'position' field).
Added 2018-02-08:
To be more precise, the issue is not technically whether the content of a file is text or binary, but rather whether or not the location of specified data can be easily calculated without reading the file from the beginning to find it. Unless text is in fixed length records, one cannot generally calculate the position of a text string without reading the file's content to find it.
Also, binary vs. text is a file open mode that (technically, if not practically) can be applied to any file, but a file must be opened in binary mode to reliably use file seek commands. For operating systems that convert new lines to multiple characters (I believe Windows still converts them to "\r\n"), the binary mode will see the two character string as two bytes and not as one character.