Вот основной и относительно быстрое решение, продолжайте читать ниже некоторого комментария:
private static string GetCase(string path)
{
DirectoryInfo dir = new DirectoryInfo(path);
if (dir.Exists)
{
string[] folders = dir.FullName.Split(Path.DirectorySeparatorChar);
dir = dir.Root;
foreach (var f in folders.Skip(1))
{
dir = dir.GetDirectories(f).First();
}
return dir.FullName;
}
else
{
return path;
}
}
Основная идея заключается в том, что получение подкаталогов из объекта DirectoryInfo приведет вас правильный случай, поэтому нам просто нужно разбить имя каталога и перейти от корня к целевому каталогу, получив правильный случай на каждом шаге.
Мой первоначальный ответ основывался на получении корпуса для каждой папки на диске, и он работал, но был медленным. Я придумал небольшое улучшение, которое сохранил результаты, но оно было слишком медленным для повседневного использования. Вы можете просмотреть историю изменений для этого комментария, если вам нужно сделать это для каждой вещи на диске, и даже тогда есть, вероятно, способы ускорить этот код. Это было «вот как вы можете это сделать», а не «вот отличный способ сделать это».
Берта, в своем ответе, пришел с идеей разделения пути на его составные части и получить часть корпуса по частям, что не приводит к огромному росту в скорости, так как вы больше не проверять все как в моем первоначальном ответе. Берту также обобщил свое решение как для файлов, так и для каталогов. В моих тестах код, вышедший выше (который использует идею Bertu «Разделить путь и сделать это по частям», но подходит к ней итеративно, а не рекурсивно) работает примерно через половину времени кода Bertu. Я не уверен, что это потому, что его метод также обрабатывает файлы, потому что его использование рекурсии приводит к дополнительным накладным расходам или потому, что он заканчивает вызов Path.GetFileName(path)
и Path.GetDirectoryName(path)
на каждой итерации. В зависимости от ваших конкретных потребностей какая-то комбинация его ответа и моей проблемы, скорее всего, решит вашу проблему, а также возможно на C#.
В этой заметке я должен упомянуть, что есть some limitations для .Net-обработки имен файлов, и поскольку для этого в .Net требуется создание большого количества объектов DirectoryInfo, вы можете рассмотреть неуправляемый код, если это ваше узкое место.
Там в нет никакой функции для этого, и попытка нормализовать строки, такие как «HElloAgain», на «helloAgain» будет проблемой, так как даже Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase («HElloAgain») вернет «Helloagain». –
@Agent, DirectoryInfo. GetDirectories() возвращает папки в случае файловой системы. – Kevin
Принято, ничего себе, я понятия не имел, что новые ответы были здесь. Спасибо и Iceman и Bertu за помощь в решении этого вопроса. – Tom