20

When is it necessary to flush a file?
I never do it because I call File.Close and I think that it is flushed automatically, isn't it?

gonutz
  • 5,087
  • 3
  • 22
  • 40
  • What makes you think that .Close() automatically flushes the bytes to storage? [The source for Close doesn't seem to indicate this](https://golang.org/src/os/file_unix.go?s=5591:5619#L179) -- am I missing anything? – Dan Esparza Sep 12 '17 at 01:07

4 Answers4

30

You'll notice that an os.File doesn't have a .Flush() because it doesn't need one because it isn't buffered. Writes to it are direct syscalls to write to the file.

When your program exits(even if it crashes) all files it has open will be closed automatically by the operating system and the file system will write your changes to disk when it gets around to it (sometimes up to few minutes after your program exits).

Calling os.File.Sync() will call the fsync() syscall which will force the file system to flush it's buffers to disk. This will guarantee that your data is on disk and persistent even if the system is powered down or the operating system crashes.

You don't need to call .Sync()

Jesse
  • 2,802
  • 20
  • 12
  • 7
    This answer confuses `fsync` with `fflush`. You don't need to _flush_ an unbuffered file. That doesn't mean you don't need to _sync_ it if you want a guarantee that the write was committed to disk. Piotr Praszmo's answer is better. – erik258 Nov 14 '17 at 01:57
  • I like the detailed explanation. You might want to change the order of the lines, first stating that you don't need to call .Sync, then adding the paragraph about how files are handled on the OS level. Good info though! – Daniel Dror Feb 17 '20 at 08:42
  • "fsync() syscall which will force the file system to flush it's buffers to disk. This will guarantee that your data is on disk and persistent even if the system is powered down or the operating system crashes." This is only the case on Linux, other operating systems act differently. – Pieter-Jan Briers Jul 19 '23 at 15:09
26

See here. File.Sync() is syscall to fsync. You should be able to find more under that name.

Keep in mind that fsync is not the same as fflush and is not executed before close.

You generally don't need to call it. The file will be written to disk anyway, after some time and if there is no power failure during this period.

cfstras
  • 1,613
  • 15
  • 21
Piotr Praszmo
  • 17,928
  • 1
  • 57
  • 65
  • 8
    "You generally don't need to call it" Which is only true if you are not working on embedded device where someone can decide to disconnect your power supply at any time. – Joppe Jan 18 '17 at 01:11
  • 1
    The problem isn't limited to just embedded devices. There's always a risk that unsynced writes die along with the in-memory buffer of a filesystem, but with modern journaled filesystems, that window is vanishingly small. Some battery-backed hardware can improve the consistency even more. `sync` is the way to make the program more aware that the underlying storage is up to date. – erik258 Nov 14 '17 at 01:59
  • calling fsync() is not enough -- you need to call fdatasync() to know that the data is fixed on disk (and then fsync() to make sure that the metadata matches) – Jon Watte Sep 13 '19 at 17:38
  • 3
    @JonWatte According to man pages `fsync` flushes everything `fdatasync` does. – Piotr Praszmo Sep 13 '19 at 20:08
  • Yes, I was confusing fsync() with sync(). Thanks for correcting! – Jon Watte Sep 15 '19 at 20:39
4

Looks the most recommendations here are to not to call fsync(), but in general it mainly depends on your application requirement. If you are working on critical file read/write, its always recommended to call fsync().

http://www.microhowto.info/howto/atomically_rewrite_the_content_of_a_file.html#idp31936

link, has more details on when file.Sync() will help.

David
  • 887
  • 8
  • 7
0

When you want to ensure data integrity as much as possible. For example, what happens if your program crashes before it comes to closing the file?

Emil Vikström
  • 90,431
  • 16
  • 141
  • 175