Some confusion around how IO works for an IOStream opened in append mode

I don’t know very much about IO, but I’m struggling a little bit with something and was just wondering if the behaviour is as expected. I create a binary file with one Float64 in it as follows:

open(fid->write(fid, 1.0), "/home/colin/aaa.dat", "w")

Now I re-open the file in append mode:

fid = open("/home/colin/aaa.dat", "a")

We have position(fid) evaluates to 8, which makes sense, since we should open at the end of the file if we want to append. Also, eof(fid) evaluates to true. However, if I do the following:


then now position(fid) evaluates to 0 as expected. But eof(fid) still evaluates to true!?! And further, if I try read(fid, Float64), I get an end-of-file error.

In other words, it seems that if I open the file in append mode, then any call to seek doesn’t actually get me away from the end of the file, even though the position call seems to indicate that I’ve moved.

Is this behaviour expected?



Note, I can see the logic in not allowing the user to write anything to any location other than the end of the file. But my understanding that reading arbitrary locations from the file should still be possible in append mode…

Though the docstring of open does not exhaustively describe the behavior of append mode, it looks quite natural to me. The append mode is designed for append data to a file, so its position should always be at the end of a file, and you cannot read data from it.

From fopen(3) - Linux manual page :

Opening a file in append mode (a as the first character of mode) causes all subsequent write operations to this stream to occur at end-of-file, as if preceded the call: fseek(stream, 0, SEEK_END);

If you’d like to read/write data from/to arbitrary position of a file, I think you should open the file with “r+” mode.

Nice link. That makes sense. It sounds like I could also use “a+” if I wanted to read from arbitrary positions, but only wanted to be able to write to the end of the file.

I guess you could maybe construct an argument that any seek call should result in an error, rather than making it seem like the position in the file has changed, even though you are really still at the end of the file, but this feels pretty low priority, as well as subjective.

Thanks for responding.



1 Like