vb.net DirectoryNotFoundException UnauthorizedAccessException FileSystem.GetFiles获取文件 异常 权限解决

来源:互联网 发布:现在还能翻墙的软件 编辑:程序博客网 时间:2024/05/10 06:09
在vb.net,如果用


My.Computer.FileSystem.GetFiles来获取文件,比如以下代码

                For Each foundFile In My.Computer.FileSystem.GetFiles(VideoFolder,                                                                      FileIO.SearchOption.SearchAllSubDirectories,                                                                      {"*.ISO", "*.mpg", "*.mkv", "*.mp4", "*.rmvb", "*.M2TS", "*.avi"})                    Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} {foundFile}")                Next

通常会因为以下文件属性为隐藏,或者没有权限而引发一些错误 ,比如

粗现异常之后,程序一般都中断或者退出,导致一个文件都获取不到。


经过分析,其实我们可以从文件夹的属性入手去解决这个问题。

一般,能在电脑上显示粗来的文件夹属性为Directory或者ReadOnly, Directory或者 System, Directory

比如电脑E盘有如下文件夹

文件夹的属性分别为:

圈圈中的文件夹就是我们上图中看到的文件夹,一般我们取到这些文件夹就可以了。

通过观察,没错!就是观察,我们发现,我们需要的文件夹属性为Directory或者ReadOnly, Directory或者 System, Directory。

文件夹:SHANXING-PC 文件夹属性:ReadOnly, Directory  这个是系统镜像文件,我们一般也是不需要的。

好了,这样的话代码差不多有了。


【建议直接拉到底下,看2016 10 23更新的代码,更加简短方便】


假如我们需要获取E盘所有目录包括子目录下的*.mkv格式的文件,代码如下:

<pre class="vb" name="code">                '先获取顶级目录下的文件                For Each foundFile In My.Computer.FileSystem.GetFiles("E:\",                                                                      FileIO.SearchOption.SearchTopLevelOnly,                                                                      {"*.mkv"})                    Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile}")                Next                '然后再获取子目录下的文件                Dim folderArr = My.Computer.FileSystem.GetDirectoryInfo("E:\")                For Each folder In folderArr.GetDirectories()'这个判断条件具有很大的局限性,也就是只能或者这两种属性的文件夹下面的文件'如果你有更好的方法,请告诉我哈~                    If folder.Attributes = FileAttributes.Directory OrElse                        folder.Attributes = FileAttributes.System + FileAttributes.Directory OrElse                        folder.Attributes = FileAttributes.System + FileAttributes.Directory + FileAttributes.ReadOnly Then                        Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件夹:{folder.FullName} 文件夹属性:{folder.Attributes.ToString()}")                        '只获取正常文件夹(在电脑上显示粗来的,只有Directory属性)下的文件                        '有些文件是Hidden, System, Directory属性,需要权限才能读取,比如System Volume Information文件夹                        For Each foundFile In folder.GetFiles("*.mkv", SearchOption.AllDirectories)                            Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile.Name}")                        Next                    End If                Next

代码写得乱糟糟 ,不要介意<img alt="大笑" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif" />


结果如下:

这样,就实现了我们需要的获取某一目录下的所有符合条件的文件。


DirectoryInfo.GetFiles 方法有个问题,就是只能只能一个格式,比如“*.txt”  "*.*"介种,假如我们想同时获取*.mkv、*.mpg格式的文件就没法实现需求了。

不过,不要灰心,还记得刚开始我们用的My.Computer.FileSystem.GetFiles吗?

没错就是再次用它!

稍微修改下代码:

                '先获取顶级目录下的文件                For Each foundFile In My.Computer.FileSystem.GetFiles("E:\",                                                                      FileIO.SearchOption.SearchTopLevelOnly,                                                                      {"*.mkv", "*.mpg"})                    Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile}")                Next                '然后再获取子目录下的文件                Dim folderArr = My.Computer.FileSystem.GetDirectoryInfo("E:\")                For Each folder In folderArr.GetDirectories()                                                                   '这个判断条件具有很大的局限性,也就是只能或者这两种属性的文件夹下面的文件'如果你有更好的方法,请告诉我哈~                    If folder.Attributes = FileAttributes.Directory OrElse                        folder.Attributes = FileAttributes.System + FileAttributes.Directory OrElse                        folder.Attributes = FileAttributes.System + FileAttributes.Directory + FileAttributes.ReadOnly Then                        Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件夹:{folder.FullName} 文件夹属性:{folder.Attributes.ToString()}")                        '只获取正常文件夹(在电脑上显示粗来的,只有Directory属性)下的文件                        '有些文件是Hidden, System, Directory属性,需要权限才能读取,比如System Volume Information文件夹                        'For Each foundFile In folder.GetFiles("*.mkv", SearchOption.AllDirectories)                        '    Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile.Name}")                        'Next                        For Each foundFile In My.Computer.FileSystem.GetFiles(folder.FullName,                                                                      FileIO.SearchOption.SearchAllSubDirectories,                                                                      {"*.mkv", "*.mpg"})                            Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile}")                        Next                    End If                Next

结果:

 


好了,需要的结果已经有了,需求实现


最后,为了防止意外导致程序中断,别忘了加上Try Catch语句。


以上代码在win7+vs2015+.net 4.0环境测试通过


继续赶项目T~T



2016 10 23 更新

由于之前没有学到有Continue这个关键字,所以搞得麻烦你很多。
用上TryCatch语句加上Continue关键字,这样,假如没有权限读取某个目录的话,会跳过这个目录,直接读取下一个目录
活到老,学到老啊~
        Dim wildCards = {"*.txt"}        Dim folderArr = My.Computer.FileSystem.GetDirectoryInfo("E:\")        '先获取主目录文件        For Each foundFile In My.Computer.FileSystem.GetFiles(folderArr.FullName,                                         FileIO.SearchOption.SearchTopLevelOnly,                                             wildCards)            Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile}")        Next        '再获取子目录文件        For Each folder In folderArr.GetDirectories()            Try                For Each foundFile In My.Computer.FileSystem.GetFiles(folder.FullName,                                                            FileIO.SearchOption.SearchAllSubDirectories,                                                                wildCards)                    Debug.Print($"来源:{New StackTrace().GetFrame(0).GetMethod.Name} 文件:{foundFile}")                Next            Catch ex As Exception                Continue For            End Try        Next



0 0