Самый эффективный способ вернуть список файлов по нескольким папкам - PullRequest
1 голос
/ 02 августа 2011

Привет всем, у меня есть следующий код, который сработает и получит все файлы из каталога маршрутов, включая подкаталоги, когда определенные критерии соответствуют В настоящее время у меня есть два метода; один, чтобы получить все файлы и добавить их в список, а затем другой метод, чтобы вернуть список. Просто интересно, является ли это лучшим способом сделать это или более эффективно объединить эти два? Или мой код может быть переписан для большей эффективности? Извините, я новичок во всем этом!

public class FileUtility
    {
        List<FileInfo> fileInfoList = new List<FileInfo>();

        public void ProcessDir(string sourceDir, String userName)
        {
            try
            {
                string userNameFirstLetter = userName.First().ToString();
                DirectoryInfo di = new DirectoryInfo(sourceDir);

                foreach (FileInfo fi in di.GetFiles())
                {
                    if (fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf")
                    {
                        if (fi.Name.Contains(userName))
                        {
                            if (fi.Name.Contains("X"))
                            {
                                if(fi.Name.First().ToString().Equals(userNameFirstLetter))
                                {
                                    if (fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName))
                                    {
                                        fileInfoList.Add(fi);
                                    }
                                }
                            }
                        }
                    }
                }

                // Recurse into subdirectories of this directory.
                string[] subdirEntries = Directory.GetDirectories(sourceDir);
                foreach (string subdir in subdirEntries)
                {
                    // Do not iterate through reparse points
                    if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
                    {
                        ProcessDir(subdir, userName);
                    }
                }
            }
            catch (DirectoryNotFoundException exp)
            {
                throw new DirectoryNotFoundException("Directory not found " + exp.Message);
            }
            catch (IOException exp)
            {
                throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message);
            }
        }

        public List<FileInfo> GetFileInfoList()
        {
            return fileInfoList;
        }
}

Ответы [ 5 ]

5 голосов
/ 02 августа 2011

Вам не нужна рекурсия.

string[] filePaths = Directory.GetFiles(@"c:\SomeDir\", "*.ext", SearchOption.AllDirectories);
2 голосов
/ 02 августа 2011

Вы можете сделать что-то вроде этого:

DirectoryInfo dir = new DirectoryInfo(@"C:\PathName");
IEnumerable<FileInfo> files = dir.GetFiles("*.*");

Тогда вы можете использовать LINQ, чтобы отфильтровать это, если вы используете C # 3.5 или выше, как я полагаю, вы. Что-то вроде:

// Only use files with userName in the filename
files = files.Where(f => f.Name.Contains(userName));

Или объединить 2:

DirectoryInfo dir = new DirectoryInfo(@"C:\PathName");
IEnumerable<FileInfo> files = dir.GetFiles("*.*").Where(f => f.Name.Contains(userName));
0 голосов
/ 02 августа 2011

Вам, вероятно, не нужен экземпляр класса.Попробуйте вместо этого сделать его статическим, например:

  public static class FileUtility
  {
    private static void ProcessDir(string sourceDir, String userName, List<FileInfo> fileInfoList)
    {
        try
        {
            string userNameFirstLetter = userName.First().ToString();
            DirectoryInfo di = new DirectoryInfo(sourceDir);

            foreach (FileInfo fi in di.GetFiles())
            {
                if ((fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf")
                    && fi.Name.Contains(userName) && fi.Name.Contains("X")
                    && fi.Name.First().ToString().Equals(userNameFirstLetter)
                    && fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName))
                 {
                    fileInfoList.Add(fi);
                 }
            }

            // Recurse into subdirectories of this directory.
            string[] subdirEntries = Directory.GetDirectories(sourceDir);
            foreach (string subdir in subdirEntries)
            {
                // Do not iterate through reparse points
                if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
                {
                    ProcessDir(subdir, userName, fileInfoList);
                }
            }
        }
        catch (DirectoryNotFoundException exp)
        {
            throw new DirectoryNotFoundException("Directory not found " + exp.Message);
        }
        catch (IOException exp)
        {
            throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message);
        }
    }

    public static List<FileInfo> GetFileInfoList(string sourceDir, string userName)
    {
        List<FileInfo> fileInfoList = new List<FileInfo>();
        ProcessDir(sourceDir, userName, fileInfoList);
        return fileInfoList;
    }
  }

Кроме того, вы можете сделать его более кратким, && И совместив критерии.

0 голосов
/ 02 августа 2011

Существует гораздо более эффективный способ сделать это.

string[] filePaths = Directory.GetFiles(rootDirectory,searchPattern,SearchOption.AllDirectories);

Вам нужно изменить searchPattern, чтобы он соответствовал вашим критериям выбора файлов.

AFAIK searchPattern работает аналогичнорегулярное выражение.

В качестве альтернативы вы можете получить все файлы, которые соответствуют определенным расширениям файлов, а затем просмотреть их, отфильтровав по вашим критериям

0 голосов
/ 02 августа 2011

Если речь идет о получении списка файлов, посмотрите ответ Пола Алана Тейлора.

Если вы хотите (немного) узнать о рекурсии: верните список файлов непосредственно из метода ProcessDir.

Использование предоставленного вами кода требует как минимум вызовов и делает его подверженным ошибкам.Особенно, если класс используется повторно.

Я изменил некоторые вещи в вашем коде:

  1. fileInfoList объявлен внутри ProcessDir
  2. , рекурсивный вызов добавляетрезультат к «текущему» результату.

    открытый класс FileUtility {

        public List<FileInfo> ProcessDir(string sourceDir, String userName)
        {
            List<FileInfo> fileInfoList = new List<FileInfo>();
    
            try
            {
                string userNameFirstLetter = userName.First().ToString();
                DirectoryInfo di = new DirectoryInfo(sourceDir);
    
                foreach (FileInfo fi in di.GetFiles())
                {
                    if (fi.Extension == ".xls" || fi.Extension == ".xlsx" || fi.Extension == ".pdf")
                    {
                        if (fi.Name.Contains(userName))
                        {
                            if (fi.Name.Contains("X"))
                            {
                                if(fi.Name.First().ToString().Equals(userNameFirstLetter))
                                {
                                    if (fi.Name.Split(Convert.ToChar("X"))[0].Equals(userName))
                                    {
                                        fileInfoList.Add(fi);
                                    }
                                }
                            }
                        }
                    }
                }
    
                // Recurse into subdirectories of this directory.
                string[] subdirEntries = Directory.GetDirectories(sourceDir);
                foreach (string subdir in subdirEntries)
                {
                    // Do not iterate through reparse points
                    if ((File.GetAttributes(subdir) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
                    {
                        fileInfoList.AddRange(ProcessDir(subdir, userName));
                    }
                }
            }
            catch (DirectoryNotFoundException exp)
            {
                throw new DirectoryNotFoundException("Directory not found " + exp.Message);
            }
            catch (IOException exp)
            {
                throw new IOException("The Process cannot access the file because it is in use by another process " + exp.Message);
            }
    
            return fileInfoList;
        }
    

    }

Примечание: Ваш кодможет быть улучшено, например, путем объединения операторов if с использованием логических и &&.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...