4 people like it.

Enumerate files without permissions errors

It's comparatively hard to enumerate files in a directory and subdirectories without getting exceptions for items you don't have permission to read. Here's a function which just ignores items you can't read and enumerates everything else. Useful for searching big network shares.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
module DirectoryExtensions

open System
open System.IO

let public SafeEnumerateFiles(path : string, searchPattern: string) =
    let safeEnumerate f path =
        try
            f(path)
        with
            | :? System.UnauthorizedAccessException -> Seq.empty

    let enumerateDirs = 
        safeEnumerate Directory.EnumerateDirectories

    let enumerateFiles =
        safeEnumerate (fun path -> Directory.EnumerateFiles(path, searchPattern))

    let rec enumerate baseDir =
        seq {
            yield! enumerateFiles baseDir
        
            for dir in enumerateDirs baseDir do
                yield! enumerate dir
        }

    enumerate path

// test
SafeEnumerateFiles(@".\clojure-1.4.0\", "*") |> Seq.iter (printfn "%s")
module DirectoryExtensions
namespace System
namespace System.IO
val SafeEnumerateFiles : path:string * searchPattern:string -> seq<string>

Full name: DirectoryExtensions.SafeEnumerateFiles
val path : string
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val searchPattern : string
val safeEnumerate : (('a -> seq<'b>) -> 'a -> seq<'b>)
val f : ('a -> seq<'b>)
val path : 'a
Multiple items
type UnauthorizedAccessException =
  inherit SystemException
  new : unit -> UnauthorizedAccessException + 2 overloads

Full name: System.UnauthorizedAccessException

--------------------
UnauthorizedAccessException() : unit
UnauthorizedAccessException(message: string) : unit
UnauthorizedAccessException(message: string, inner: exn) : unit
module Seq

from Microsoft.FSharp.Collections
val empty<'T> : seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.empty
val enumerateDirs : (string -> seq<string>)
type Directory =
  static member CreateDirectory : path:string -> DirectoryInfo + 1 overload
  static member Delete : path:string -> unit + 1 overload
  static member EnumerateDirectories : path:string -> IEnumerable<string> + 2 overloads
  static member EnumerateFileSystemEntries : path:string -> IEnumerable<string> + 2 overloads
  static member EnumerateFiles : path:string -> IEnumerable<string> + 2 overloads
  static member Exists : path:string -> bool
  static member GetAccessControl : path:string -> DirectorySecurity + 1 overload
  static member GetCreationTime : path:string -> DateTime
  static member GetCreationTimeUtc : path:string -> DateTime
  static member GetCurrentDirectory : unit -> string
  ...

Full name: System.IO.Directory
Directory.EnumerateDirectories(path: string) : Collections.Generic.IEnumerable<string>
Directory.EnumerateDirectories(path: string, searchPattern: string) : Collections.Generic.IEnumerable<string>
Directory.EnumerateDirectories(path: string, searchPattern: string, searchOption: SearchOption) : Collections.Generic.IEnumerable<string>
val enumerateFiles : (string -> seq<string>)
Directory.EnumerateFiles(path: string) : Collections.Generic.IEnumerable<string>
Directory.EnumerateFiles(path: string, searchPattern: string) : Collections.Generic.IEnumerable<string>
Directory.EnumerateFiles(path: string, searchPattern: string, searchOption: SearchOption) : Collections.Generic.IEnumerable<string>
val enumerate : (string -> seq<string>)
val baseDir : string
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val dir : string
val iter : action:('T -> unit) -> source:seq<'T> -> unit

Full name: Microsoft.FSharp.Collections.Seq.iter
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn

More information

Link:http://fssnip.net/fp
Posted:11 years ago
Author:Kit Eason
Tags: files , io , searching