Благоприятный для новичка метод для получения списка всех файлов и каталогов

Объяснение , почему Вы получаете ту ошибку: PCRE использует свободное определение Perl того, каков разделитель. Ваши внешние [] с похожи на допустимые разделители к нему, заставляя его читать [:punct:] как regex часть.

(О, и избегают ereg функции, если Вы можете - они не собираются быть включенными в PHP 5.3.)

5
задан Adam Kane 10 October 2009 в 04:01
поделиться

6 ответов

Я полагаю, вы ищете существующий метод GetFileSystemInfos (string, SearchOptions). Если вы укажете AllDirectories в качестве значения SearchOptions, он будет рекурсивно искать переданные в папке.

Например:

public static List<FileSystemInfo> GetAllFilesAndDirectories ( string dir ) {
  DirectoryInfo info = new DirectoryInfo(dir);
  FileSystemInfo[] all = info.GetFileSystemInfos("*", SearchOptions.AllDirectories);
  return new List<FileSystemInfo>(all);
}

Если вы хотите написать долгий путь, вы можете сделать следующее

public static List<FileSystemInfo> GetAllFilesAndDirectories ( string dir ) {
  int i = 0; 
  List<DirectoryInfo> toProcess = new List<DirectoryInfo>();
  List<FileSystemInfo> list = new List<FileSystemInfo>();
  toProcess.Add(new DirectoryInfo(dir));
  while ( i < toProcess.Count ) { 
    DirectoryInfo curDir = toProcess[i];
    foreach ( FileSystemInfo curFile in curDir.GetFileSystemInfos() ) {
      list.Add(curFile);
      DirectoryInfo maybe = curFile as DirectoryInfo;
      if ( maybe != null ) {
        toProcess.Add(maybe);
      }
    i++;
  }
  return list;
}

  FileSystemInfo[] all = info.GetFileSystemInfos("*", SearchOptions.AllDirectories);
  return new List<FileSystemInfo>(all);
}
1
ответ дан 15 December 2019 в 01:06
поделиться

Если вы хотите "удобный для новичков метод", я могу предложить метод bobbymcr .

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

static IEnumerable<FileSystemInfo> GetAllFilesAndDirectories(string path)
{
    string currentDirectory = "";
    string[] files = Directory.GetFiles( // skip empty subfolders
        path, "*.*", SearchOption.AllDirectories);
    foreach (string file in files)
    {
        if(currentDirectory != Path.GetDirectoryName(file))
        {
            // First time in this directory: return it
            currentDirectory = Path.GetDirectoryName(file);
            yield return new DirectoryInfo(currentDirectory);
        }

        yield return new FileInfo(file);
    }
}
0
ответ дан 15 December 2019 в 01:06
поделиться

Я думаю, что с точки зрения читабельности кода лучше всего написать рекурсивную функцию. Рекурсивная функция - это функция, которая вызывает себя до тех пор, пока не достигнет точки, в которой не нужно вызывать какую-либо другую функцию.

Для иллюстрации факториал n, записанный как n! и определяемая как величина 1 x 2 x 3 x ... xn (где n - положительное целое число) может быть довольно легко определена рекурсивным способом следующим образом.

public int factorial(int n)
{
    if (n < 0)
    {
        throw new Exception("A factorial cannot be calculated for negative integers.");
    }

    if (n == 0 || n == 1)
    {
        // end condition, where we do not need to make a recursive call anymore
        return 1;
    }
    else
    {
        // recursive call
        return n * factorial(n - 1);
    }
}

NB: 0! и 1! определены равными 1.

Аналогичным образом, метод для перечисления всех файлов и папок по заданному пути также может быть определен рекурсивно. Это потому, что файлы и папки имеют рекурсивную структуру.

Следовательно, будет работать следующий метод:

public static List<FileSystemInfo> GetAllFilesAndFolders(string folder)
{
    // NOTE : We are performing some basic sanity checking
    // on the method's formal parameters here
    if (string.IsNullOrEmpty(folder))
    {
        throw new ArgumentException("An empty string is not a valid path.", "folder");
    }
    if (!Directory.Exists(folder))
    {
        throw new ArgumentException("The string must be an existing path.", "folder");
    }

    List<FileSystemInfo> fileSystemInfos = new List<FileSystemInfo>();

    try
    {
        foreach (string filePath in Directory.GetFiles(folder, "*.*"))
        {
            // NOTE : We will add a FileSystemInfo object for each file found
            fileSystemInfos.Add(new FileInfo(filePath));
        }
    }
    catch
    {
        // NOTE : We are swallowing all exceptions here
        // Ideally they should be surfaced, and at least logged somewhere
        // Most of these will be security/permissions related, i.e.,
        // the Directory.GetFiles method will throw an exception if it
        // does not have security privileges to enumerate files in a folder.
    }
    try
    {
        foreach (string folderPath in Directory.GetDirectories(folder, "*"))
        {
            // NOTE : We will add a FileSystemInfo object for each directory found
            fileSystemInfos.Add(new DirectoryInfo(folderPath));

            // NOTE : We will also add all FileSystemInfo objects found under
            // each directory we find
            fileSystemInfos.AddRange(GetAllFilesAndFolders(folderPath));
        }
    }
    catch
    {
        // NOTE : We are swallowing all exceptions here
        // Ideally they should be surfaced, and at least logged somewhere
        // Most of these will be security/permissions related, i.e.,
        // the Directory.GetDirectories method will throw an exception if it
        // does not have security privileges to enumerate files in a folder.
    }

    return fileSystemInfos;
}

Следует отметить, что этот метод будет "ходить" вся структура каталогов под папкой и НЕ вернется, пока она не "пройдется" по всей иерархии. Следовательно, возврат может занять много времени, если нужно найти много объектов.

Также следует отметить, что читаемость этого метода может быть дополнительно улучшена с помощью лямбда-выражений и методов расширения.

NB : Проблема с использованием Directory.GetFiles и Directory.GetDirectories для рекурсии подпапок заключается в том, что при возникновении каких-либо исключений (например, связанных с разрешениями безопасности) метод ничего не возвращает, тогда как рекурсивное выполнение вручную позволяет обрабатывать эти исключения и все же получить набор файлов обратно.

0
ответ дан 15 December 2019 в 01:06
поделиться

Вот самый короткий способ, который я могу придумать:

static List<FileSystemInfo> GetAllFilesAndDirectories(string dir)
{
    DirectoryInfo dirInfo = new DirectoryInfo(dir);            
    List<FileSystemInfo> allFilesAndDirectories = new List<FileSystemInfo>();

    allFilesAndDirectories.AddRange(dirInfo.GetFiles("*", SearchOption.AllDirectories));
    allFilesAndDirectories.AddRange(dirInfo.GetDirectories("*", SearchOption.AllDirectories));

    return allFilesAndDirectories;
}

Он вернет список всех файлов и каталогов на всех уровнях, начиная с заданного пути. Они будут возвращены в следующем порядке: все файлы, а затем все каталоги.

2
ответ дан 15 December 2019 в 01:06
поделиться

Вы специально просили "сделать это глупее". Я думаю, что два других ответа очень хороши, но вот еще один способ сделать это с еще более простым, легко понятным кодом начального уровня.

http://support.microsoft.com/kb/303974

Править

Я знаю, что это не 3.0, но это все еще испытанный, проверенный и простой для понимания способ сделать это.

0
ответ дан 15 December 2019 в 01:06
поделиться
    public List<Object> GetFilesAndDirectories(string path)
    {
        List<Object> lst = new List<Object>();
        string[] dirs = null;

        try
        {
            dirs = Directory.GetDirectories(path);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

        foreach (string d in dirs)
        {
            string[] files = null;

            try
            {
                files = Directory.GetFiles(d);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            foreach (string f in files)
            {
                lst.Add(f);
            }

            lst.Add(d);

            lst.AddRange(GetFilesAndDirectories(d));
        }

        return lst;
    }


List<Object> stuff = GetFilesAndDirectories(someRoot);
1
ответ дан 15 December 2019 в 01:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: