Мое приложение С# 3.5 работает на Windows 7 Ultimate, 64 бит. Он выполняет все папки вложенных папок для выполнения своей работы. Однако он терпит неудачу (попадает в бесконечный цикл до исключения StackOverflow.com), если выполняется против папки, имя которой является только одним символом, который равен # 255.
Чтобы воспроизвести, вы можете сделать следующее:
- запустите Windows Explorer, создав папку C:\Temp в этой папке
- создайте новую папку и переименуйте ее с помощью Alt-255 (используя цифровую клавиатуру)
- создать подпапки "first" и "second" there
- создать подпапки "1" и "2" в разделе "Темп
Итак, теперь у вас есть:
- C:\1
- C:\2
- C:\\ first
- C:\\ second
Для такой папки C:\Temp с подпапкой с именем # 255 (или более # 255 символов) приведен следующий код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
class Program
{
public static string[] GetDirectories(string pathToTraverse)
{
List<string> result = new List<string>();
foreach (DirectoryInfo subFolder in new DirectoryInfo(pathToTraverse).GetDirectories())
{
result.Add(subFolder.FullName);
}
return result.ToArray();
}
public static void TraverseFolders(string folderToTraverse)
{
foreach (string subFolder in GetDirectories(folderToTraverse))
{
Console.WriteLine(subFolder);
TraverseFolders(subFolder);
}
}
static void Main(string[] args)
{
TraverseFolders(@"C:\Temp");
}
}
никогда не закончится и даст вам результат:
C:\Temp\
C:\Temp\1
C:\Temp\2
C:\Temp\
C:\Temp\1
C:\Temp\2
C:\Temp\
C:\Temp\1
C:\Temp\2
C:\Temp\
Итак, как правильно перечислить такие папки вложенных папок?
Ответ 1
Следующая программа работает отлично и не приводит к ошибке.
using System;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string pathToTraverse = @"C:\Desktop";
foreach (DirectoryInfo subFolder in new DirectoryInfo(pathToTraverse).GetDirectories())
{
System.Console.WriteLine(subFolder);
}
}
}
}
Он производит следующий вывод:
chaff
Python
__history
ÿ
Предпоследняя видимая пустая строка на самом деле является каталогом с именем Alt + 255.
Следовательно, я считаю, что ваша проблема не связана с кодом, который вы показали, и фактически находится в другом месте в некотором коде, который вы нам не предоставили.
Я работаю в Windows 7 с таргетингом VS 2010 Express.net 3.5.
Теперь, когда ваше обновление показывает весь ваш код, я вижу, что происходит. Код .net, по-видимому, обрезает каталоги, и поэтому папки с пробелом теряются.
Итак, @"C:\Temp\ "
обрезается до @"C:\Temp\"
.
Я обнаружил, что следующая тривиальная модификация избегала бесконечного цикла:
TraverseFolders(subFolder+@"\");
Добавление разделителя конечных путей останавливает обрезку, которая появляется в вызове в DirectoryInfo. В приведенном выше примере это означает, что @"C:\Temp\ \"
передается в DirectoryInfo, что дает ожидаемые результаты.
Я предполагаю, что вы, вероятно, должны использовать процедуру, которая добавляет только разделитель пути назад, если он еще не присутствует. И вы можете захотеть избежать hardcoding @ "\" в качестве разделителя путей, но для вас теперь нужно понять, что вы знаете, какова основная причина вашей проблемы.
Ответ 2
Символ ASCII 255 полностью не поддерживается Windows. Для визуальных целей он переводит этот символ в символ "_".
Причина?
Символ ASCII 255 отображается как невидимый символ, но занимает одно пространство символов, поэтому путаница между этим символом и символом ASCII 32 SPACE. Этот символ работает только в Windows 98 и более низких версиях, включая все версии DOS (если я не ошибаюсь).
РЕДАКТИРОВАТЬ: Windows 7 теперь имеет некоторое исправление с некоторыми расширенными символами. Код должен обрабатываться отлично, если он работает на этой ОС.
Решение?
Не используйте этот символ как имя файла и папки, потому что ваша программа.
или
-
Позволяет программе проверять расширенные символы и пропускать их, если они существуют до того, как они будут выполняться бесконечно.
-
Разрешить программе папки с расширенными символами, но если в случае непрерывности цикла, поместите код, который пропустит эту папку и переместится к следующему элементу папки.
-
Ваш код должен работать с Vista и Windows 7, сделать это требование вашей программы.
Ответ 3
Почему у вас есть папка с именем "_"? Это не описательно вообще. Идея папки состоит в том, что вы можете содержать все связанные файлы в этой папке и, возможно, использовать подпапки, чтобы группировать их еще больше; имена папок обычно должны быть описательными - например, у многих сайтов есть папка с именем "css" или "stylesheets". Сомневаюсь, что мне нужно объяснить, для чего они предназначены, поскольку они довольно понятны. Я лично не могу подумайте об одной ситуации, когда я буду использовать 1 символ для имени папки. Лучше всего, на мой взгляд, придерживаться буквенно-цифровых символов и редко использовать символы (это безопаснее, поскольку вы никогда не сталкивались с этими ситуациями в любой операционной системе).