首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >快速获取特定路径下的所有文件和目录

快速获取特定路径下的所有文件和目录
EN

Stack Overflow用户
提问于 2011-05-20 00:41:50
回答 4查看 171K关注 0票数 67

我正在创建一个备份应用程序,c#在其中扫描目录。在我使用类似这样的东西来获取一个目录中的所有文件和子文件之前:

代码语言:javascript
复制
DirectoryInfo di = new DirectoryInfo("A:\\");
var directories= di.GetFiles("*", SearchOption.AllDirectories);

foreach (FileInfo d in directories)
{
       //Add files to a list so that later they can be compared to see if each file
       // needs to be copid or not
}

唯一的问题是,有时一个文件不能被访问,我得到几个错误。我得到的一个错误的例子是:

因此,我创建了一个递归方法,它将扫描当前目录中的所有文件。如果该目录中有目录,则将再次调用该方法来传递该目录。这种方法的好处是,我可以将文件放在try catch块中,如果没有错误,可以选择将这些文件添加到列表中;如果出现错误,可以将目录添加到另一个列表中。

代码语言:javascript
复制
try
{
    files = di.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);               
}
catch
{
     //info of this folder was not able to get
     lstFilesErrors.Add(sDir(di));
     return;
}

所以这个方法效果很好,唯一的问题是,当我扫描一个大的目录时,它会花费很多时间。我怎样才能加速这个过程呢?我的实际方法是这样做,以防您需要它。

代码语言:javascript
复制
private void startScan(DirectoryInfo di)
{
    //lstFilesErrors is a list of MyFile objects
    // I created that class because I wanted to store more specific information
    // about a file such as its comparePath name and other properties that I need 
    // in order to compare it with another list

    // lstFiles is a list of MyFile objects that store all the files
    // that are contained in path that I want to scan

    FileInfo[] files = null;
    DirectoryInfo[] directories = null;
    string searchPattern = "*.*";

    try
    {
        files = di.GetFiles(searchPattern, SearchOption.TopDirectoryOnly);               
    }
    catch
    {
        //info of this folder was not able to get
        lstFilesErrors.Add(sDir(di));
        return;
    }

    // if there are files in the directory then add those files to the list
    if (files != null)
    {
        foreach (FileInfo f in files)
        {
            lstFiles.Add(sFile(f));
        }
    }


    try
    {
        directories = di.GetDirectories(searchPattern, SearchOption.TopDirectoryOnly);
    }
    catch
    {
        lstFilesErrors.Add(sDir(di));
        return;
    }

    // if that directory has more directories then add them to the list then 
    // execute this function
    if (directories != null)
        foreach (DirectoryInfo d in directories)
        {
            FileInfo[] subFiles = null;
            DirectoryInfo[] subDir = null;

            bool isThereAnError = false;

            try
            {
                subFiles = d.GetFiles();
                subDir = d.GetDirectories();

            }
            catch
            {
                isThereAnError = true;                                                
            }

            if (isThereAnError)
                lstFilesErrors.Add(sDir(d));
            else
            {
                lstFiles.Add(sDir(d));
                startScan(d);
            }


        }

}

如果我尝试用下面这样的东西来处理异常,那么问题就来了:

代码语言:javascript
复制
DirectoryInfo di = new DirectoryInfo("A:\\");
FileInfo[] directories = null;
            try
            {
                directories = di.GetFiles("*", SearchOption.AllDirectories);

            }
            catch (UnauthorizedAccessException e)
            {
                Console.WriteLine("There was an error with UnauthorizedAccessException");
            }
            catch
            {
                Console.WriteLine("There was antother error");
            }

如果发生异常,我就得不到任何文件。

EN

回答 4

Stack Overflow用户

发布于 2011-05-20 01:54:10

这种方法要快得多。您只能在一个目录中放置大量文件时才能使用。我的A:\外置硬盘几乎有1TB的容量,所以在处理大量文件时会有很大的不同。

代码语言:javascript
复制
static void Main(string[] args)
{
    DirectoryInfo di = new DirectoryInfo("A:\\");
    FullDirList(di, "*");
    Console.WriteLine("Done");
    Console.Read();
}

static List<FileInfo> files = new List<FileInfo>();  // List that will hold the files and subfiles in path
static List<DirectoryInfo> folders = new List<DirectoryInfo>(); // List that hold direcotries that cannot be accessed
static void FullDirList(DirectoryInfo dir, string searchPattern)
{
    // Console.WriteLine("Directory {0}", dir.FullName);
    // list the files
    try
    {
        foreach (FileInfo f in dir.GetFiles(searchPattern))
        {
            //Console.WriteLine("File {0}", f.FullName);
            files.Add(f);                    
        }
    }
    catch
    {
        Console.WriteLine("Directory {0}  \n could not be accessed!!!!", dir.FullName);                
        return;  // We alredy got an error trying to access dir so dont try to access it again
    }

    // process each directory
    // If I have been able to see the files in the directory I should also be able 
    // to look at its directories so I dont think I should place this in a try catch block
    foreach (DirectoryInfo d in dir.GetDirectories())
    {
        folders.Add(d);
        FullDirList(d, searchPattern);                    
    }

}

顺便说一句,我得到这个感谢你的评论,吉姆·米歇尔

票数 46
EN

Stack Overflow用户

发布于 2011-05-20 01:06:49

在.NET 4.0中,有一个Directory.EnumerateFiles方法,它返回一个IEnumerable<string>,并且不会加载内存中的所有文件。只有当你开始迭代返回的集合时,文件才会被返回和exceptions could be handled

票数 19
EN

Stack Overflow用户

发布于 2012-10-20 08:40:47

我知道这很古老,但是...另一种选择可能是像这样使用FileSystemWatcher:

代码语言:javascript
复制
void SomeMethod()
{
    System.IO.FileSystemWatcher m_Watcher = new System.IO.FileSystemWatcher();
    m_Watcher.Path = path;
    m_Watcher.Filter = "*.*";
    m_Watcher.NotifyFilter = m_Watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
    m_Watcher.Created += new FileSystemEventHandler(OnChanged);
    m_Watcher.EnableRaisingEvents = true;
}

private void OnChanged(object sender, FileSystemEventArgs e)
    {
        string path = e.FullPath;

        lock (listLock)
        {
            pathsToUpload.Add(path);
        }
    }

这将允许您使用一个非常轻量级的过程来监视目录中的文件更改,然后您可以使用它来存储更改的文件的名称,以便您可以在适当的时间备份它们。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6061957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档