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.
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?