views:

458

answers:

2

How do you flush the io buffer in Erlang?

For instace:

io:format("hello") or io:format(user, "hello")

This post seems to indicate that there is no clean solution.

Is there a better solution than in that post?

+2  A: 

Sadly other than properly implementing a flush "command" in the io/kernel subsystems and making sure that the low level drivers that implement the actual io support such a command you really have to simply rely on the system quiescing before closing. A failing I think.

Have a look at io.erl/io_lib.erl in stdlib and file_io_server.erl/prim_file.erl in kernel for the gory details.

As an example, in file_io_server (which effectively takes the request from io/io_lib and routes it to the correct driver), the command types are:

{put_chars,Chars}
{get_until,...}
{get_chars,...}
{get_line,...}
{setopts, ...}

(i.e. no flush)!

As an alternative you could of course always close your output (which would force a flush) after every write. A logging module I have does something like this every time and it doesn't appear to be that slow (it's a gen_server with the logging received via cast messages):

  case file:open(LogFile, [append]) of
    {ok, IODevice} ->
 io:fwrite(IODevice, "~n~2..0B ~2..0B ~4..0B, ~2..0B:~2..0B:~2..0B: ~-8s : ~-20s : ~12w : ",
    [Day, Month, Year, Hour, Minute, Second, Priority, Module, Pid]),
 io:fwrite(IODevice, Msg, Params),
 io:fwrite(IODevice, "~c", [13]),
 file:close(IODevice);
Alan Moore
Not that I have ever done it, but from my understanding implementing an io server is not that complex, especially as you can use io_lib for some of the more complex requests. I think you are on to something with the file module, using the file:sync/1 call one can sync the output explicitly. It will just not be done using an io-call, but a custom message, unless one tie it to the io:nl(IO) request.
Christian
+1  A: 

you could run

flush().

from the shell, or try

flush()->
receive
 _ -> flush()
after 0 -> ok
end.

That works more or less like a C flush.

Fonz