Как определить, учитывает ли файловая система регистр in.net?

есть ли у .net способ определить, чувствительна ли локальная файловая система к регистру?

7 ответов


вы можете создать файл в папке temp (используя имя файла в нижнем регистре), затем проверить, существует ли файл (используя имя файла в верхнем регистре), e.g:

string file = Path.GetTempPath() + Guid.NewGuid().ToString().ToLower();
File.CreateText(file).Close();
bool isCaseInsensitive = File.Exists(file.ToUpper());
File.Delete(file);

в библиотеке классов .NET нет такой функции.

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

редактировать: вы можете просто взять первый файл в корневом каталоге, а затем проверить, оба ли файла.ToLower () и filename.ToUpper (существовать). К сожалению, это довольно возможно, что существуют как прописные, так и строчные варианты одного и того же файла, поэтому вы должны сравнить FileInfo.Свойства Name как строчных, так и прописных вариантов, чтобы увидеть, действительно ли они одинаковы или нет. Это не потребует записи на диск.

очевидно, что это не удастся, если на томе вообще нет файлов. В этом случае просто вернитесь к первому варианту (см. ответ Мартина для реализации).


имейте в виду, что у вас может быть несколько файловых систем с разными правилами корпусе. Например, корневая файловая система может быть чувствительной к регистру, но вы можете иметь файловую систему без регистра (например, USB-накопитель с файловой системой FAT), смонтированную где-то. Поэтому, если вы делаете такие проверки, убедитесь, что вы делаете их в каталоге, к которому вы собираетесь получить доступ.

кроме того, что делать, если пользователь копирует данные, скажем, с учетом регистра в файловой системе без учета регистра? Если у вас есть файлы, которые отличаются только случаем, один из них будет перезаписывать другой, вызывая потерю данных. При копировании в другом направлении вы также можете столкнуться с проблемами, например, если файл A содержит ссылку на файл "b", но на самом деле файл называется "B". Это работает в исходной файловой системе без учета регистра, но не в системе с учетом регистра.

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


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


Это не функция .NET, но функции GetVolumeInformation и GetVolumeInformationByHandleW из API Windows будут делать то, что вы хотите (см. параметр yje lpFileSystemFlags.


/// <summary>
/// Check whether the operating system is case-sensitive.
/// For instance on Linux you can have two files/folders called
//// "test" and "TEST", but on Windows the two can not coexist.
/// This method does not extend to mounted filesystems, which might have different properties.
/// </summary>
/// <returns>true if the operating system is case-sensitive</returns>
public static bool IsFileSystemCaseSensitive()
{
    // Actually try.
    string file = Path.GetTempPath() + Guid.NewGuid().ToString().ToLower() + "test";
    File.CreateText(file).Close();
    bool result = File.Exists(file.ToUpper());
    File.Delete(file);

    return result;
}

на основе ответа M4N со следующими изменениями:

  • статические имена, так что мы уверены, что он содержит букву, а не только цифры.
  • может быть более читабельным?
  • обернутый в метод.
  • документация.

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


Я вызываю обманщика:

Path.DirectorySeparatorChar == '\' ? "I'm insensitive" : "I'm probably sensitive"