Search code examples
iosmlsmlnj

TextIO.outputSubstr() does not write anything


I have a really annoying problem.

This function:

fun writeAFile() =
  let
    val outstream = TextIO.openOut "look_at_me_im_a_file.txt"
  in
    TextIO.outputSubstr(outstream,Substring.full("I'm so sad right now :("))
  end;

Just creates the file look_at_me_im_a_file.txt but it's empty. I get no errors and it does not work with either SML/NJ or PolyML. I have no problems reading from files.


Solution

  • First of all, Substring.full isn't needed - it doesn't really do anything other than give you something of the substring type. Instead, you can do:

    TextIO.output (outstream, "I'm so sad right now :(");
    

    Now, the reason it doesn't work:

    When you tell sml to write something to a file (using TextIO.output or TextIO.outputSubstr) it doesn't actually write it in the file right away. It writes to a buffer. Well, sometimes it writes to the file right away, but not often enough that you can depend on it.

    Now, this seems terribly impractical, but it's more efficient - if you tell it to write several small pieces of data after each other, it can just lump it all together in one write operation.

    The way to get around it is to tell sml "Hey, I really want that write to happen right now." There's a function just for that, which is called TextIO.flushOut. Alternatively, closing the stream will also cause everything to be written.

    Actually, you should always remember to close your streams. Leaving open file handles lying around is messy - how will the filesystem know that you're done with it, and that it can let other programs write to the file?