Быстрый способ перечисления всех файлов, включая подпапки - PullRequest
4 голосов
/ 28 июня 2009

Кто-нибудь знает более быстрый способ перечисления через каталог и подпапки, чтобы собрать все файлы в перечислении? Вот что у меня сейчас:

Public Shared allFiles() As String
allFiles = Directory.GetFiles(<ServerLocation>, "*.*", SearchOption.AllDirectories)

Спасибо! JFV

РЕДАКТИРОВАТЬ: я перечисляю эти файлы из расположения сервера. Я не знаю, изменит ли это перспективу этого вопроса или нет. Спасибо за все вклады до сих пор!

Ответы [ 4 ]

4 голосов
/ 28 июня 2009

Краткий ответ:

Если этот код функционально корректен для вашего проекта, и вы не доказали, что это проблема с профилировщиком, не изменяйте его. Продолжайте использовать функционально правильное решение, пока не докажете, что оно медленное.

Длинный ответ:

Насколько быстрым или медленным является этот конкретный фрагмент кода, зависит от много факторов. Многие из которых будут зависеть от конкретной машины, на которой вы работаете (например, скорость жесткого диска). Глядя на код, который включает файловую систему и ничего более, очень трудно сказать «х быстрее, чем у» с какой-либо степенью уверенности.

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

Если это окажется проблемой, тогда вы можете вызвать PInvoke в FindFirstFile / FindNextFile и получать их по одному за раз. Результат будет, вероятно, функционально медленнее в циклах ЦП, но будет иметь меньшую нагрузку на память.

Но я должен подчеркнуть, что вы должны доказать, что это проблемы, прежде чем исправить их.

3 голосов
/ 16 ноября 2010

с использованием System.Collections.Generic;

private static List<string> GetFilesRecursive(string b)
{

             // 1.
            // Store results in the file results list.
            List<string> result = new List<string>();

            // 2.
            // Store a stack of our directories.
            Stack<string> stack = new Stack<string>();

            // 3.
            // Add initial directory.
            stack.Push(b);

            // 4.
            // Continue while there are directories to process
            while (stack.Count > 0)
            {
                // A.
                // Get top directory
                string dir = stack.Pop();

                try
                {
                    // B
                    // Add all files at this directory to the result List.
                    result.AddRange(Directory.GetFiles(dir, "*.*"));

                    // C
                    // Add all directories at this directory.
                    foreach (string dn in Directory.GetDirectories(dir))
                    {
                        stack.Push(dn);
                    }
                }
                catch
                {
                    // D
                    // Could not open the directory
                }
            }
            return result;
        }

Реквизиты оригинальной статьи: http://www.codeproject.com/KB/cs/workerthread.aspx

0 голосов
/ 06 декабря 2011

Вот мое решение. Первоначальный запуск немного медленный, я работаю над этим. Объект my.computer.filesystem, вероятно, является проблемой для медленного запуска. Но этот метод выведет список из 31 000 файлов в течение 5 минут по сети.

Imports System.Threading

Public Class ThreadWork

Public Shared Sub DoWork()
    Dim i As Integer = 1
    For Each File As String In My.Computer.FileSystem.GetFiles("\\172.16.1.66\usr2\syscon\S4_650\production\base_prog", FileIO.SearchOption.SearchTopLevelOnly, "*.S4")
        Console.WriteLine(i & ". " & File)
        i += 1
    Next
End Sub 'DoWork
End Class 'ThreadWork

Module Module1

Sub Main()
    Dim myThreadDelegate As New ThreadStart(AddressOf ThreadWork.DoWork)
    Dim myThread As New Thread(myThreadDelegate)
    myThread.Start()
    '"Pause" the console to read the data.
    Console.ReadLine()
End Sub 'Main

End Module
0 голосов
/ 28 июня 2009

Это грубый способ сделать это.

dir /s /b

Получите вывод этого в текстовый файл, прочитайте его и разделите на \r\n.
Запустите приведенную выше команду в определенном каталоге, чтобы посмотреть, поможет ли это.

Чтобы получить только каталоги

dir /s /b /ad

Чтобы получить только файлы

dir /s /b /a-d

РЕДАКТИРОВАТЬ: Джаред прав, говоря, что не использовать другие подходы, если ваш подход не доказал медленный.

...