Idiomatic way to get directory size in F#

Viewed 105

I want to get the total directory size, including all sub-directories and files. There are two ways I can think to do this, the first is to get a list of all the file attributes (FileInfo in .NET) of all the files, and then just sum together all the Length properties like this:

listOfFileInfos |> List.sumBy (fun f -> f.Length)

The other way would be to add the file size of each file to an accumulator as we traverse the directory structure. So we wouldn't be building a big list, we'd just be adding to the total as we go. I'm not really sure how to do this in F# though!

Which way is more idiomatic? The first one looks easier to me but I'm only a beginner in functional programming.

1 Answers

The issue here is not so much about how to do the sum (sumBy works fine for that), but how to iterate over all files - you say that you want to do this over all sub-folders, which means that plain Directory.GetFiles will not do.

To handle sub-directories, you can us an overload that takes SearchOptions:

Directory.GetFiles("C:/temp", "*", SearchOption.AllDirectories)

This returns an array, which may be wasteful for directories with a lot of files, so a better option is EnumerateFiles, which returns a lazy sequence:

Directory.EnumerateFiles("C:/temp", "*", SearchOption.AllDirectories)

If you then sum the lengths using Seq.sumBy, the computation will iterate over all files without ever building a large data structure to keep them all in memory:

Directory.EnumerateFiles("C:/temp", "*", SearchOption.AllDirectories)
|> Seq.sumBy (fun f -> FileInfo(f).Length)
Related