Reputation: 4736
I have a command-line journaling application written in Ruby. I'd like the ability to back-date new entries and have the entries written to the file in chronological order. These are multi-line entries, so a simple sort after the fact isn't sufficient. I know how to append a line to the end of a text file:
def write(file, entry)
open(file, 'r+') do |f|
f.write entry
end
end
However, let's say I have a variable called line_number
that contains the position I want to start writing to. Is there a simple way to write entry
into file
starting at line number line_number
, while preserving the original content?
For example, given a file with contents:
a
c
A call to the method write_at(file, 2, 'b')
should yield:
a
b
c
Upvotes: 2
Views: 307
Reputation: 4950
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.
Upvotes: 1