Write a circular file in c++

Kram picture Kram · May 20, 2009 · Viewed 12k times · Source

I need to write a circular file in c++. The program has to write lines in a file and when the code reaches a maximum number of lines, it must overwrite the lines in the beginning of the file.

Anyone have any idea?

Answer

Noldorin picture Noldorin · May 20, 2009

Unfortunately you can't truncate/overwrite lines at the beginning of a file without rewriting the entire thing.

New Suggestion

I've just thought of a new approach that might do the trick for you...

You could include a small header to your file that has the following structure.

Edit: Rubbish, I've just described a variant of a circular buffer!

Header Fields

  • Bytes 00 - 07 (long) - Total (current) number of lines written to the file.
  • Bytes 08 - 15 (long) - Pointer to the start of the "actual" first line of your file. This will initially be the byte after the header ends, but will change later when data gets overridden.`
  • Bytes 16 - 23 (long) - Length of the "end section" of the file. Again, this will initially be zero, but will change later when data gets overridden.

Read Algorithm (Pseudocode)

Reads the entire file.

Read the header field that points to the start of the "actual" first line
Read the header field that specifies the length of the "end section"
Read every line until the end of the file
Seek to the byte just after the end of the header
Read every line until the "end section" has been fully read

Write Algorithm (Pseudocode)

Writes an arbitrary number of new lines to the file.

Read the header field that contains the total no. of lines in the file
If (line count) + (no. of new lines) <= (maximum no. of lines) Then
    Append new lines to end of file
    Increment header field for line count by (no. of ne lines)
Else
    Append as many lines as possible (up to maximum) to end of file
    Beginning at pointer to first line (in header field), read as many lines as still need to be written
    Find the total byte count of the lines just read
    Set the header field that points to the first line to the next byte in the stream
    Keep writing the new lines to the end of the file, each at a time, until the byte count of the remaining lines is less than the byte count of the lines at the beginning of the file (it may be that this condition is true immediately, in which case you don't need to write any more)
    Write the remaining new lines to the start of the file (starting at the byte after the header)
    Set the header field that contains the length of the "end section" of the file to the number of bytes just written after the header.

Not a terribly simple algorith, I fully admit! I nonetheless think it's quite elegant in a way. Let me know if any of that isn't clear, of course. Hopefully it should do precisely what you want now.

Original Suggestion

Now, if you're lines are guaranteed to be of constant length (in bytes), you could easily enough just seek back to the appropiate point and overwrite existing data. This would seem like a rather unlikely situation however. If you don't mind imposing the restriction that your lines must have a maximum length, and additionally padding each of the lines you write to this maximum length, then that could make matters easy for you. Still, it has its disadvantages such as greatly increasing file size under certain circumstances (i.e. most lines are much shorted than the maximum length.) It all depends on the situation whether this is acceptable or not...

Finally, you may instead want to look at utilising an existing logging system, depending on your exact purpose.