1

Does closing an fstream guarantee a sync to the filesystem? I'm debating this with a co-worker and would need a definite reference. I'm intersted in what the standard says and also in what happens on windows with the Visual Studio implementation.

Also, if close doesn't imply a sync, is there a standard C++ way to ensure the sync is done?

static_rtti
  • 53,760
  • 47
  • 136
  • 192
  • see answer at: http://stackoverflow.com/a/13358458/717732 – quetzalcoatl Oct 22 '13 at 08:56
  • possible duplicate of [Force write of a file to disk](http://stackoverflow.com/questions/13358431/force-write-of-a-file-to-disk) -- it is not _exact_ duplicate of this question, but one of the good answers precisely matches. – quetzalcoatl Oct 22 '13 at 08:56
  • ahh, you'd like a reference to the standard? so, maybe include the `language-lawyer` tag? its not very relevant, but it'd mark the point a bit. – quetzalcoatl Oct 22 '13 at 08:58
  • @quetzalcoatl : it's not a real duplicate, because I'm concerned about actual syncing of the filesystem, not only flushing to the OS. I would like to be sure the data is on the disk when my program returns (because another program is going to read it right after that). – static_rtti Oct 22 '13 at 09:04
  • So basically there are two questions in one: 1) does close() imply flush(), and 2) is there a standard c++ way of doing a filesystem flush, and if not, how do you do it on windows? – static_rtti Oct 22 '13 at 09:05
  • @quetzalcoatl : also the linked question does not ask about windows. – static_rtti Oct 22 '13 at 09:06
  • 1
    You don't need to be concerned about whether the 'data is on the disk' for a following program. Even if it's only in the file system cache, the following program will see it. Otherwise the OS would be badly broken. You can certainly rely on `fclose()` implying `fflush().` – user207421 Oct 22 '13 at 09:06
  • The `close()` method is pretty much the last chance a stream/streambuf has to talk to the environment to ask the data to be written down. The standard says it's equivalent to `fclose()`, which the C standard says disassociates (and possibly de-allocates) the buffers. Whether or not the data is durable, is not the language's concern any more. [Check out what database systems do to ensure the data went all the way to the physical device.](http://www.postgresql.org/docs/9.3/static/runtime-config-wal.html) – DanielKO Oct 22 '13 at 09:12
  • @DanielKO I don't believe that the standard really says that '`close()` is equivalent to `fclose().`' It might possibly say the reverse, but somehow I doubt it. There are `stdio` buffers to be flushed, which makes it not equivalent at all. – user207421 Oct 22 '13 at 09:15
  • 2
    @EJP: then read the standard and stop guessing: § 27.9.1.4 (aka [filebuf.members]), item 6: "... the function closes the file (as if by calling `std::fclose(file)`)." – DanielKO Oct 22 '13 at 09:18
  • @DanielKO : so you say the buffers are disallocated when `close()` is called. Does that mean they are flushed before? Or are their contents lost? – static_rtti Oct 22 '13 at 09:23
  • 2
    @static_rtti From the C11 draft (I don't have the final document): 7.21.5.1 says "A successful call to the fclose function causes the stream pointed to by stream to be flushed and the associated file to be closed. Any unwritten buffered data for the stream are delivered to the host environment to be written to the file [...]". What would be the point of closing a file if data could be lost? This if course doesn't guarantee the OS isn't caching the operations somewhere, that's the OS' problem now, read the OS documentation. On POSIX we can use `fsync()` to ensure the data is safe. – DanielKO Oct 22 '13 at 09:33

2 Answers2

1

I'm quite sure it's already sorted out how closing the filestream closes the buffers. So, now, the buffers:

draft of Std'1998: 27.8.1.3.6: basic_filebuf* close();

6 Effects: If is_open() == false, returns a null pointer. If a put area exists, calls overflow(EOF) to flush characters. (...) Finally it closes the file (‘‘as if’’ by calling std::fclose(file)).308) If any of the calls to overflow or std::fclose fails then close fails.

Now, see the overflow(): 27.8.1.4.8 (...)

I've then tried to trace it further, somewhere down there were some references to sync and sputc, but I was unable to trace the exact wording for how overflow guarantees flushing. It surely does, but sorry, my time's up today :/

quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
0

std::basic_filebuf::close calls std::fclose, which states that: "Any unwritten buffered data are flushed to the OS", or according to the C99 standard draft n1256, "Any unwritten buffered data for the stream are delivered to the host environment to be written to the file".

Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45