Title here
Summary here
Our first example demonstrates reading files in F#. Reading and writing files are basic tasks needed for many F# programs. Let’s look at some examples of reading files.
open System
open System.IO
// Reading files requires checking most operations for errors.
// This helper will streamline our error checks below.
let check (result: Result<'T, exn>) =
match result with
| Ok value -> value
| Error e -> raise e
[<EntryPoint>]
let main argv =
// Perhaps the most basic file reading task is
// slurping a file's entire contents into memory.
let dat =
File.ReadAllText("/tmp/dat")
|> check
printfn "%s" 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 FileStream.
use f = new FileStream("/tmp/dat", FileMode.Open)
// Read some bytes from the beginning of the file.
// Allow up to 5 to be read but also note how many
// actually were read.
let b1 = Array.zeroCreate 5
let n1 = f.Read(b1, 0, b1.Length)
printfn "%d bytes: %s" n1 (System.Text.Encoding.UTF8.GetString(b1, 0, n1))
// You can also seek to a known location in the file
// and read from there.
f.Seek(6L, SeekOrigin.Begin) |> ignore
let b2 = Array.zeroCreate 2
let n2 = f.Read(b2, 0, b2.Length)
printfn "%d bytes @ %d: %s" n2 6 (System.Text.Encoding.UTF8.GetString(b2, 0, n2))
// Other methods of seeking are relative to the
// current cursor position,
f.Seek(4L, SeekOrigin.Current) |> ignore
// and relative to the end of the file.
f.Seek(-10L, SeekOrigin.End) |> ignore
// The FileStream provides some functions that may
// be helpful for file reading. For example, reads
// like the ones above can be more robustly
// implemented with ReadExactly.
f.Seek(6L, SeekOrigin.Begin) |> ignore
let b3 = Array.zeroCreate 2
f.ReadExactly(b3, 0, b3.Length)
printfn "%d bytes @ %d: %s" b3.Length 6 (System.Text.Encoding.UTF8.GetString(b3))
// There is no built-in rewind, but
// Seek(0, SeekOrigin.Begin) accomplishes this.
f.Seek(0L, SeekOrigin.Begin) |> ignore
// The StreamReader class implements a buffered
// reader that may be useful both for its efficiency
// with many small reads and because of the additional
// reading methods it provides.
use r4 = new StreamReader(f)
let b4 = r4.ReadLine()
printfn "5 bytes: %s" (b4.Substring(0, 5))
// The 'use' keyword ensures that the file is closed
// when we're done (it's equivalent to 'using' in C#)
0 // return an integer exit code
To run the program:
$ echo "hello" > /tmp/dat
$ echo "f#" >> /tmp/dat
$ dotnet run
hello
f#
5 bytes: hello
2 bytes @ 6: f#
2 bytes @ 6: f#
5 bytes: hello
Next, we’ll look at writing files.