f#检查目录是否可访问且不工作
我试图检查目录是否可访问,这样我就不会出现“拒绝访问”错误,但它不起作用,也不会跳过循环,因为通常不鼓励将异常作为控制流的一部分。在尝试枚举目录内容之前,最好先检查目录的适当访问权限。试着这样做:f#检查目录是否可访问且不工作,f#,directory,F#,Directory,我试图检查目录是否可访问,这样我就不会出现“拒绝访问”错误,但它不起作用,也不会跳过循环,因为通常不鼓励将异常作为控制流的一部分。在尝试枚举目录内容之前,最好先检查目录的适当访问权限。试着这样做: try (box (Directory.GetDirectories(dir) )) with | :? System.UnauthorizedAccessException -> () 开放系统 开放系统 开放系统 open System.Security.AccessControl 开放
try (box (Directory.GetDirectories(dir) ))
with | :? System.UnauthorizedAccessException -> ()
开放系统
开放系统
开放系统
open System.Security.AccessControl
开放系统.Security.Principal
让我们检查一下安全性=
让帐户=sprintf@“%s\%s”环境。UserDomainName环境。用户名
让identity=WindowsIdentity.GetCurrent()
让主体=身份|>WindowsPrincipal
让isAdmin=identity.Owner=identity.User
乐趣(目录:DirectoryInfo)->
尝试
让acl=dir.GetAccessControl(AccessControlSections.All)
let rules=acl.GetAccessRules(true、true、typeof)
类型()的规则
|>Seq.filter(乐趣规则->规则.IdentityReference.Value.Equals(account、StringComparison.CurrentCultureIgnoreCase)|
(如果rule.IdentityReference.Value.Equals(“内置\Administrators”,StringComparison.CurrentCultureIgnoreCase)
然后是isAdmin&&principal.IsInRole(rule.IdentityReference.Value)
else principal.IsInRole(rule.IdentityReference.Value)))
|>Seq.exists(有趣的规则->(rule.FileSystemRights&&FileSystemRights.Read=FileSystemRights.Read)&&rule.AccessControlType AccessControlType.Deny)
带有| 124;->
假的
let rec getFiles(目录:DirectoryInfo)=
[if check security dir
然后对于dir.GetFiles(“*”)中的文件,请生成文件
对于dir.GetDirectories(“*”)中的subDir,请生成!getFiles subDir
]
let dir=DirectoryInfo(@“C:\Temp”)
dir |>getFiles
您可能会遇到一些其他问题,如果出现异常,try with
块应该能够处理它,因此您实际上没有遇到异常,或者周围的代码中存在一些其他问题。你为什么要选择框
在.NET中,对使用异常作为控制流的厌恶是有道理的。在OCaml中,异常被广泛用于此目的,但它们很便宜。在.NET中,这在性能方面更昂贵。也就是说,有时您确实希望捕获并处理异常,所以我认为这不是一个大问题。例如,该示例可以工作:
open System
open System.IO
open System.Linq
open System.Security.AccessControl
open System.Security.Principal
let checkSecurity =
let account = sprintf @"%s\%s" Environment.UserDomainName Environment.UserName
let identity = WindowsIdentity.GetCurrent()
let principal = identity |> WindowsPrincipal
let isAdmin = identity.Owner = identity.User
fun (dir: DirectoryInfo) ->
try
let acl = dir.GetAccessControl(AccessControlSections.All)
let rules = acl.GetAccessRules(true, true, typeof<NTAccount>)
rules.OfType<FileSystemAccessRule>()
|> Seq.filter (fun rule -> rule.IdentityReference.Value.Equals(account, StringComparison.CurrentCultureIgnoreCase) ||
(if rule.IdentityReference.Value.Equals("BUILTIN\Administrators", StringComparison.CurrentCultureIgnoreCase)
then isAdmin && principal.IsInRole(rule.IdentityReference.Value)
else principal.IsInRole(rule.IdentityReference.Value)))
|> Seq.exists (fun rule -> (rule.FileSystemRights &&& FileSystemRights.Read = FileSystemRights.Read) && rule.AccessControlType <> AccessControlType.Deny)
with | _ ->
false
let rec getFiles (dir: DirectoryInfo) =
[ if checkSecurity dir
then for file in dir.GetFiles("*") do yield file
for subDir in dir.GetDirectories("*") do yield! getFiles subDir
]
let dir = DirectoryInfo(@"C:\Temp")
dir |> getFiles
open System.IO
let okdir = @"c:\tmp"
let baddir = @"L:\Finance"
let checkDir dir =
try
Directory.GetDirectories(dir) |> ignore
printfn "%A" "Processed"
with
| :? System.UnauthorizedAccessException as ex -> failwith ex.Message
| :? System.IO.IOException as ex -> failwith ex.Message
// | :? System.Exception as ex -> failwith ex.Message
checkDir okdir
//"Processed"
//val it : unit = ()
checkDir baddir
//System.Exception: Access to the path 'L:\Finance' is denied.