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: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
module DirectoryExtensions

open System
open System.IO

/// As System.IO.Directory.EnumerateFiles() but ignoring any files
/// or directories which cannot be accessed, eg. because of 
/// permissions.
///
/// Always recurses into subdirectories.
///
let public SafeEnumerateFiles(path : string, searchPattern: string) =
    // Attempts to list the directories below the specified path, and fails silently (empty result) if permission denied.
    let tryEnumerateDirs path =
        try
            Directory.EnumerateDirectories(path)
        with
            // Silently fail if we don't have access to list subdirs:
            | :? System.UnauthorizedAccessException -> Seq.empty

    // Attempts to list the files the specified path, and fails silently (empty result) if permission denied.
    let tryEnumerateFiles path namePattern =
        try
            Directory.EnumerateFiles(path, namePattern)
        with
            // Silently fail if we don't have access to list files:
            | :? System.UnauthorizedAccessException -> Seq.empty

    // Lists all directories below (and including) the specified directory.
    let rec dirsUnder (basePath : string) : seq<string> =
        seq {
            yield! [|basePath|]
            for subDir in tryEnumerateDirs(basePath) do
                yield! dirsUnder subDir
        }

    dirsUnder path
    |> Seq.map (fun path -> tryEnumerateFiles path searchPattern) 
    |> Seq.concat

// Usage examples:
//
// F#: SafeEnumerateFiles(@"x:\mybigdir", "*.*") |> Seq.length
//
// C#: Console.WriteLine(DirectoryExtensions.SafeEnumerateFiles(@"x:\mybigdir", @"*.*").Count());
module DirectoryExtensions
namespace System
namespace System.IO
val SafeEnumerateFiles : path:string * searchPattern:string -> seq<string>

Full name: DirectoryExtensions.SafeEnumerateFiles


 As System.IO.Directory.EnumerateFiles() but ignoring any files
 or directories which cannot be accessed, eg. because of
 permissions.

 Always recurses into subdirectories.
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 tryEnumerateDirs : (string -> Collections.Generic.IEnumerable<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>
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 tryEnumerateFiles : (string -> string -> Collections.Generic.IEnumerable<string>)
val namePattern : 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 dirsUnder : (string -> seq<string>)
val basePath : 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 subDir : string
val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U>

Full name: Microsoft.FSharp.Collections.Seq.map
val concat : sources:seq<#seq<'T>> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.concat
Next Version Raw view Test code New version

More information

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