Как определить, учитывает ли файловая система регистр 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"