Reading Files in Standard ML Here’s the translation of the Go code for reading files into Standard ML:
(* Reading and writing files are basic tasks needed for
many Standard ML programs. First we'll look at some examples of
reading files. *)
(* Helper function to handle exceptions *)
fun check f x =
f x
handle e => ( print ( "Error: " ^ exnMessage e ^ " \n " ); raise e )
(* Perhaps the most basic file reading task is
slurping a file's entire contents into memory. *)
val dat = check ( TextIO. openIn >> TextIO. inputAll ) "/tmp/dat"
val _ = print dat
(* You'll often want more control over how and what
parts of a file are read. For these tasks, start
by opening a file to obtain a TextIO.instream value. *)
val f = check TextIO. openIn "/tmp/dat"
(* Read some bytes from the beginning of the file.
Allow up to 5 to be read but also note how many
actually were read. *)
val b1 = check ( TextIO. inputN f ) 5
val _ = print ( Int. toString ( String. size b1 ) ^ " bytes: " ^ b1 ^ " \n " )
(* You can also seek to a known location in the file
and read from there. *)
val _ = check ( TextIO.StreamIO. setPosition ( TextIO. getInstream f )) 6
val b2 = check ( TextIO. inputN f ) 2
val _ = print ( "2 bytes @ 6: " ^ b2 ^ " \n " )
(* Other methods of seeking are relative to the
current cursor position, *)
val _ = check ( TextIO.StreamIO. skipChars ( TextIO. getInstream f )) 4
(* and relative to the end of the file. *)
val _ = check ( TextIO.StreamIO. setPosition ( TextIO. getInstream f ))
( TextIO.StreamIO. endPosition ( TextIO. getInstream f ) - 10 )
(* The TextIO structure provides some functions that may
be helpful for file reading. For example, reads
like the ones above can be more robustly
implemented with inputN. *)
val _ = check ( TextIO.StreamIO. setPosition ( TextIO. getInstream f )) 6
val b3 = check ( TextIO. inputN f ) 2
val _ = print ( "2 bytes @ 6: " ^ b3 ^ " \n " )
(* There is no built-in rewind, but
setPosition 0 accomplishes this. *)
val _ = check ( TextIO.StreamIO. setPosition ( TextIO. getInstream f )) 0
(* The TextIO structure implements buffered
reading that may be useful both for its efficiency
with many small reads and because of the additional
reading methods it provides. *)
val b4 = check ( TextIO. inputN f ) 5
val _ = print ( "5 bytes: " ^ b4 ^ " \n " )
(* Close the file when you're done *)
val _ = TextIO. closeIn f
To run this program:
$ echo "hello" > /tmp/dat
$ echo "ml" >> /tmp/dat
$ sml reading-files.sml
hello
ml
5 bytes: hello
2 bytes @ 6: ml
2 bytes @ 6: ml
5 bytes: hello
This Standard ML code demonstrates various file reading operations, including:
Reading an entire file into memory Opening a file and reading specific portions Seeking to different positions in the file Using buffered reading Note that Standard ML’s file I/O operations are primarily based on the TextIO
structure, which provides functions for text-based file operations. The exact equivalents of some Go operations (like Peek
) are not available, but similar functionality can be achieved using the provided functions.
Also, error handling in Standard ML is typically done using exceptions, which is why we’ve defined a check
function to handle potential errors.
Next, we’ll look at writing files.