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.
Комплексный, хотя, возможно, немного устаревший.