4 people like it.
Like the snippet!
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
More information