C# сравнение строки пути к файлу без учета регистра

Я хотел бы сравнить две строки, содержащие пути к файлам в С#.

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

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


person Cedric Mamo    schedule 07.10.2014    source источник
comment
Если вы действительно просто хотите выполнить сравнение строк, нижеприведенные ответы могут сработать. Однако простое сравнение строк не покажет, относятся ли два пути к одному и тому же фактическому файловому объекту. Для функции ac#, которая правильно сообщит вам, относятся ли два пути к одному и тому же файлу, см. /а>.   -  person David I. McIntosh    schedule 31.03.2018


Ответы (4)


Из MSDN:

Строковое поведение файловой системы, ключей и значений реестра, а также переменных среды лучше всего представлено StringComparison.OrdinalIgnoreCase.

И:

При интерпретации имен файлов, файлов cookie или чего-либо еще, где может встречаться комбинация, такая как «å», порядковые сравнения по-прежнему обеспечивают наиболее прозрачное и подходящее поведение.

Поэтому это просто:

String.Equals(fileNameA, fileNameB, StringComparison.OrdinalIgnoreCase)

(Я всегда использую статический вызов Equals в случае, если левый операнд равен null)

person Lucas Trzesniewski    schedule 07.10.2014
comment
Спасибо! Это именно то, что я искал. - person Cedric Mamo; 07.10.2014
comment
Я понимаю, что вопрос просто задавался, как сравнить два имени файла без учета регистра, но можно предположить, что цель такого сравнения состоит в том, чтобы попытаться определить, относятся ли два имени файла к одному и тому же объекту. Если вы хотите определить, относятся ли два имени файла к одному и тому же файлу, это не поможет. Следует отметить, что невероятно сложно определить, относятся ли два имени файла к одному и тому же файловому объекту, учитывая возможность соединений, ссылок, общих ресурсов в сетях и т. д. См. stackoverflow.com/a/39399232/1082063. - person David I. McIntosh; 12.10.2016

При сравнении путей направление разделителя пути также очень важно. Например:

 bool isEqual = String.Equals("myFolder\myFile.xaml", "myFolder/myFile.xaml", StringComparison.OrdinalIgnoreCase);

isEqual будет false.

Поэтому сначала необходимо исправить пути:

 private string FixPath(string path)
    {
        return path.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
                   .ToUpperInvariant();
    }

Тогда как это выражение будет true:

bool isEqual = String.Equals(FixPath("myFolder\myFile.xaml"), FixPath("myFolder/myFile.xaml"), StringComparison.OrdinalIgnoreCase);
person Mr.B    schedule 23.08.2016

string path1 = "C:\\TEST";
string path2 = "c:\\test";

if(path1.ToLower() == path2.ToLower())
    MessageBox.Show("True");

Вы имеете в виду это или я не понял вопроса?

person Vajura    schedule 07.10.2014
comment
Хотя это точно работает для английских символов, я до сих пор не знаю, как Windows на самом деле обрабатывает международные символы. Это моя проблема. Если бы это было так, было бы лучше использовать String.Compare(string,string,StringComparison), так как это не создавало бы две новые строки. Я хочу быть уверен, что сравнение строк использует те же правила регистра, что и ntfs. - person Cedric Mamo; 07.10.2014
comment
хм, я почти уверен, что и tolower, и strongcomparison работают с любой культурой, поскольку они пытаются перевести его в нижний регистр, если в этом языке существует нижний регистр. Скопируйте и вставьте некоторые иностранные наборы в строки и протестируйте их таким образом. - person Vajura; 07.10.2014
comment
Я знаю, что это работает, но вы неправильно поняли вопрос. Я уже знаю, как выполнять поиск без учета регистра. Я спросил, какие правила нечувствительности к регистру следует использовать. На вопрос ответили выше. - person Cedric Mamo; 07.10.2014

я бы пошел на

string.Compare(path1, path2, true) == 0

или если вы хотите указать культуры:

string.Compare(path1, path2, true, CultureInfo.CurrentCulture) == 0 

использование ToUpper делает бесполезное выделение памяти каждый раз, когда вы что-то сравниваете

person Serve Laurijssen    schedule 07.10.2014
comment
Я знаю, как сравнивать две строки без учета регистра. В чем я хочу быть уверен, так это в том, что нечувствительность к регистру использует те же правила регистра, что и NTFS. Использует ли ntfs текущую культуру? - person Cedric Mamo; 07.10.2014