Question

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.

Was it helpful?

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?

OTHER TIPS

Being an rookie i didn't check our lecture notes :/

a functioning version of the code is

fun writeAFile() =
let
        val outstream = TextIO.openOut "look_at_me_im_a_file.txt"
in
    (
        TextIO.output(outstream,"I'm so glad right now :)");
        TextIO.closeOut(outstream)
    )
end;

Although its noteworthy that the online documentation at http://www.standardml.org/Basis/text-io.html only gives a vague reference to the output function.

And looking at the documentation for the IMPERATIVE_IO says val output : outstream * vector -> unit which is confusing since it is non apparent that string is actually of type CharVector.vector and is thus a valid argument for the output function.

I hope this will be of help to some other rookie out there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top