Friday, May 14, 2010

F# FileInfo, DirectoryInfo and DriveInfo

Recent changes in my day job have sidetracked me from doing much development or working with F#. However, to prevent myself from getting rusty with F# development, I decided to pick up the book Visual C# 2010 Recipes by Allen Jones, Adam Freeman, Matthew MacDonald, and Rakesh Rajan and randomly work through some of the recipes in F#. I've also incorporated Alex Gorbatchev's Syntax Highligher along with Steve Gilham's F# brush in this blog so source code syntax coloring will start to look very different from before.

Here is a translation of Recipe 5.1 to F# 2.0:

(*  Recipe 5.1. Retrieve Information About a File, Directory or Drive *)
// An interesting aspect when writing this recipe was trying to write
// the display function.  A StackOverflow entry help me to understand
// the printf format string.
// http://stackoverflow.com/questions/2162081/type-of-printfn-in-f-static-vs-dynamic-string
open System
open System.IO

(* Having some fun with pipeline operators... *)
let display  (stuff : (string * string) list) =
    List.iter (fun (fmt,text) ->  Printf.TextWriterFormat unit>(fmt) |> printfn  <| text) stuff

let displayFile (file:FileInfo) =
    [("File created: %s",file.CreationTime.ToString());
     ("File last updated: %s",file.LastWriteTime.ToString());
     ("File last accessed: %s",file.LastAccessTime.ToString());
     ("File size (bytes): %s",file.Length.ToString());
     ("File attribute list: %s",file.Attributes.ToString());]
    |> display
    
let displayDirectory  (dir:DirectoryInfo) =
    [("Directory created: %s ",dir.CreationTime.ToString());
     ("Directory last updated: %s",dir.LastWriteTime.ToString());
     ("Directory last accessed: %s",dir.LastAccessTime.ToString());
     ("Directory attribute list: %s",dir.Attributes.ToString());
     ("Directory contains: %s files",dir.GetFiles().Length.ToString());]
    |> display

let displayDrive (drive:DriveInfo) =
    [("Drive type: %s", drive.DriveType.ToString());
     ("Drive format: %s", drive.DriveFormat.ToString());
     ("Drive free space: %s", drive.AvailableFreeSpace.ToString());]
    |> display
    

let args = fsi.CommandLineArgs
if args.Length = 1 then
    printfn "Please supply a filename."
    exit 1
    
let file = new FileInfo(args.[1])
if file.Exists then
    displayFile file

    
let dir = file.Directory
[("Checking directory: %s",dir.Name);
 ("In directory: %s",dir.Parent.Name);
 ("Directory exists : %s",dir.Exists.ToString());]
|> display 

if dir.Exists then
    displayDirectory dir
    
let drv = new DriveInfo(file.FullName)

[("Drive: %s",drv.Name);] |> display
if drv.IsReady then
    displayDrive drv
    
Environment.NewLine |> Console.WriteLine
"Main method completed. Press Enter" |> printfn "%s"
Console.ReadLine()