现在的位置: 首页 > 综合 > 正文

.NET(C#):枚举文件夹内的所有文件

2013年02月05日 ⁄ 综合 ⁄ 共 4189字 ⁄ 字号 评论关闭

简单,不过不是很直接。虽然.NET Framework中提供列举全部子文件的方法,如下:

string[] files = Directory.GetFiles(@"C:\", "*", SearchOption.AllDirectories);

 

问题是一旦有一个文件夹发生错误,结果异常抛出,然后什么也不会返回。

 

我写了一个类:FolderExplorer,使用它的ListFiles方法会返回指定文件夹内返回所有可以返回文件,无法访问的子文件夹会跳过。使用Error事件可以查看发生的错误。

 

举个非常简单的例子:

var folderExplorer = new FolderExplorer();

folderExplorer.Error += (sender, e) =>

    {

        Console.WriteLine("错误 - 文件夹:{0}, 消息:{1}", e.FolderPath, e.ErrorMessage);

    };

 

//枚举子文件

foreach (var file in folderExplorer.ListFiles(@"C:\a"))

    Console.WriteLine(file);

 

输出示例:

错误 - 文件夹:C:\a\x\b, 消息:Access to the path 'C:\a\x\b\' is denied.

错误 - 文件夹:C:\a\y, 消息:Access to the path 'C:\a\y\' is denied.

C:\a\a.txt

C:\a\x\a.bmp

C:\a\x\a.zip

C:\a\x\a\a.xls

 

 

该类型有.NET Framework 4.0+实现,用到了Directory.EnumerateFiles(返回IEnumerable<string>而不是GetFiles方法的string[])和LINQ。

也有.NET Framework 2.0+实现,在2.0下用一个全局的List<string>来保存子文件。

 

读者可以下载或者在下面浏览源代码。

 

源代码下载
下载地址
注意:此为微软SkyDrive存档,请用浏览器直接下载,用某些下载工具可能无法下载
文件类型:.cs文件

 

 

.NET Framework 4.0实现代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

 

namespace Mgen

{

    //文件枚举 .NET 4.0 +

    //Updates: http://www.cnblogs.com/mgen/archive/2012/04/10/2440570.html

    public class FolderExplorer

    {

        #region 错误事件

 

        public event EventHandler<FolderErrorEventArgs> Error;

 

        protected virtual void OnError(FolderErrorEventArgs e)

        {

            var handler = this.Error;

            if (handler != null)

                handler(this, e);

        }

 

        #endregion

 

        /// <summary>

        /// 枚举文件夹内的所有文件

        /// </summary>

        /// <param name="folder"></param>

        /// <returns></returns>

        public IEnumerable<string> ListFiles(string folder)

        {

            if (folder == null)

                throw new ArgumentNullException("folder");

 

            return InternalListFiles(folder);

        }

 

        #region 私有方法

 

        IEnumerable<string> InternalListFiles(string folder)

        {

            try

            {

                var files = Directory.EnumerateFiles(folder);

                foreach (var dir in Directory.EnumerateDirectories(folder))

                    files = files.Concat(InternalListFiles(dir));

 

                return files;

            }

            catch (Exception ex)

            {

                OnError(new FolderErrorEventArgs(folder, ex.Message));

                return Enumerable.Empty<string>();

            }

        }

 

        #endregion

 

 

    }

 

    // 错误事件参数

    public class FolderErrorEventArgs : EventArgs

    {

        public string FolderPath { get; private set; }

        public string ErrorMessage { get; private set; }

 

        public FolderErrorEventArgs(string folder, string err)

        {

            FolderPath = folder;

            ErrorMessage = err;

        }

    }

 

}

 

 

 

.NET Framework 2.0+实现代码:

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

 

namespace Mgen

{

    //文件枚举 .NET 2.0 +

    //Updates: http://www.cnblogs.com/mgen/archive/2012/04/10/2440570.html

    public class FolderExplorer

    {

        #region 错误事件

 

        public event EventHandler<FolderErrorEventArgs> Error;

 

        protected virtual void OnError(FolderErrorEventArgs e)

        {

            var handler = this.Error;

            if (handler != null)

                handler(this, e);

        }

 

        #endregion

 

        /// <summary>

        /// 枚举文件夹内的所有文件

        /// </summary>

        /// <param name="folder"></param>

        /// <returns></returns>

        public string[] ListFiles(string folder)

        {

            if (folder == null)

                throw new ArgumentNullException("folder");

 

            var result = new List<string>();

            InternalListFiles(folder, result);

            return result.ToArray();

        }

 

        #region 私有方法

 

        void InternalListFiles(string folder, List<string> result)

        {

            try

            {

                result.AddRange(Directory.GetFiles(folder));

 

                foreach (var dir in Directory.GetDirectories(folder))

                    InternalListFiles(dir, result);

            }

            catch (Exception ex)

            {

                OnError(new FolderErrorEventArgs(folder, ex.Message));

            }

        }

 

        #endregion

 

 

    }

 

    // 错误事件参数

    public class FolderErrorEventArgs : EventArgs

    {

        public string FolderPath { get; private set; }

        public string ErrorMessage { get; private set; }

 

        public FolderErrorEventArgs(string folder, string err)

        {

            FolderPath = folder;

            ErrorMessage = err;

        }

    }

 

}

 

 

 

 

:D

抱歉!评论已关闭.