C# Как я могу решить ограничения при использовании DirectoryInfo?

Когда я рекурсивно просматриваю некоторые папки и файлы, я сталкиваюсь с этой ошибкой:

Указанный путь, имя файла или оба слишком длинные. Полное имя файла должно быть не более 260 символов, а имя каталога должно быть не более 248 символов.

Вот моя функция

private void ProcessDirectory(DirectoryInfo di)
{
    try
    {
        DirectoryInfo[] diArr = di.GetDirectories();

        foreach (DirectoryInfo directoryInfo in diArr)
        {
            if (StopCheck)
                    return;
            ProcessDirectory(directoryInfo);
        }
        ProcessFile(di);
    }
    catch (Exception e)
    {
        listBoxError.Items.Add(e.Message);
    }

    TextBoxCurrentFolder.Text = di.ToString();
}

Я не могу сделать имена каталогов короче, потому что мне тоже не позволено... Как я могу решить эту проблему?

Добавлено: вот другая функция:

private void ProcessFile(DirectoryInfo di)
{
    try
    {
        FileInfo[] fileInfo = di.GetFiles();

        if (fileInfo.LongLength != 0)
        {
            foreach (FileInfo info in fileInfo)
            {
                Size += info.Length;
                CountFile++;
            }
        }
    }
    catch (Exception e)
    {
        listBoxError.Items.Add(e.Message);
    }
}

РЕДАКТИРОВАТЬ Нашел здесь, где он использовал Zeta Long Paths: Как я могу использовать класс FileInfo, избегая исключений PathTooLongException?

Реализовали это, и теперь я собираюсь позволить программе работать всю ночь, чтобы посмотреть, работает ли она.

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

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

5 ответов

Решение

Вот больше информации о библиотеке Delimon, упомянутой ранее. Это библиотека на основе.NET Framework 4 на Microsoft TechNet для преодоления проблемы длинных имен файлов:

Библиотека Delimon.Win32.I O (V4.0).

Он имеет свои собственные версии ключевых методов из System.IO. Например, вы бы заменили:

System.IO.Directory.GetFiles 

с

Delimon.Win32.IO.Directory.GetFiles

что позволит вам обрабатывать длинные файлы и папки.

С веб-сайта:

Delimon.Win32.IO заменяет основные файловые функции System.IO и поддерживает имена файлов и папок длиной до 32 767 символов.

Эта библиотека написана на.NET Framework 4.0 и может использоваться в системах x86 и x64. Ограничения "Файл и папка" стандартного пространства имен System.IO могут работать с файлами, содержащими 260 символов в имени файла и 240 символов в имени папки (MAX_PATH обычно настраивается как 260 символов). Обычно вы сталкиваетесь с ошибкой System.IO.PathTooLongException со стандартной библиотекой.NET.

Это известное ограничение в Windows: http://msdn.microsoft.com/en-us/library/aa365247.aspx

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

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

РЕДАКТИРОВАТЬ: На самом деле может быть обходной путь: http://www.codinghorror.com/blog/2006/11/filesystem-paths-how-long-is-too-long.html

Вы можете использовать команду subst. Он создает виртуальный диск, начиная с любой папки, которую вы передаете в качестве параметра.

Например, вы можете включить путь c:\aaaaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaaaaaaaa\aaaaaaaaaaaaaa в привод R: и продолжить изучение подпапки с: \ aaaaaaaaaaaaaaaaaaaaaa \ aaaaaaaaaaaaaaaaaaaa \ aaaaaaaaaaaaaa через R:...

Ты знаешь, что я имею в виду?

Вам нужно будет использовать P/Invoke и Unicode-версию функций Win32 API. Тебе понадобиться FindFirstFile, FindNextFile а также FindClose функции.

Также см:

Я также рекомендую прочитать этот блог из трех частей от команды BCL, опубликованный в 2007 году, но относящийся конкретно к ограничениям DirectoryInfo, когда речь идет о глубоко вложенных папках. Он охватывает историю ограничения MAX_PATH, новый формат \?\ Path и различные решения и обходные пути на основе.NET.

Комплексный, хотя, возможно, немного устаревший.

Другие вопросы по тегам