Получение фактического имени файла (с надлежащим преобразованием регистра) в Windows с.NET

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

33
задан Community 23 May 2017 в 12:09
поделиться

3 ответа

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

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

я создал метод, который возьмет путь (папка или файл) и возвратит правильно версию в жестком переплете из него (для всего пути):

    public static string GetExactPathName(string pathName)
    {
        if (!(File.Exists(pathName) || Directory.Exists(pathName)))
            return pathName;

        var di = new DirectoryInfo(pathName);

        if (di.Parent != null) {
            return Path.Combine(
                GetExactPathName(di.Parent.FullName), 
                di.Parent.GetFileSystemInfos(di.Name)[0].Name);
        } else {
            return di.Name.ToUpper();
        }
    }

Вот некоторые тестовые сценарии, которые работали над моей машиной:

    static void Main(string[] args)
    {
        string file1 = @"c:\documents and settings\administrator\ntuser.dat";
        string file2 = @"c:\pagefile.sys";
        string file3 = @"c:\windows\system32\cmd.exe";
        string file4 = @"c:\program files\common files";
        string file5 = @"ddd";

        Console.WriteLine(GetExactPathName(file1));
        Console.WriteLine(GetExactPathName(file2));
        Console.WriteLine(GetExactPathName(file3));
        Console.WriteLine(GetExactPathName(file4));
        Console.WriteLine(GetExactPathName(file5));

        Console.ReadLine();
    }

метод возвратит поставляемую стоимость, если файл не сделает существует.

могли бы быть более быстрые методы (это использует рекурсию), но я не уверен, есть ли какие-либо очевидные способы сделать это.

25
ответ дан 27 November 2019 в 18:36
поделиться

Интересная проблема.

Один способ сделать это состоит в том, чтобы "найти" файл на основе нечувствительного к регистру имени и затем посмотреть на FileInfo. Свойство FullName. Я протестировал это использование следующей функции, и это дает необходимый результат.

static string GetCaseSensitiveFileName(string filePath)
{
    string caseSensitiveFilePath = null;

    DirectoryInfo dirInfo = new DirectoryInfo(Path.GetDirectoryName(filePath));
    FileInfo[] files = dirInfo.GetFiles(Path.GetFileName(filePath));
    if (files.Length > 0)
    {
        caseSensitiveFilePath = files[0].FullName;
    }

    return caseSensitiveFilePath;
}
-1
ответ дан 11 October 2019 в 00:27
поделиться

Я думаю единственный способ, которым Вы собираетесь быть способными сделать, это при помощи того же API Win32, а именно, метод SHGetFileInfo, упомянутый в принятом ответе для вопроса, на который Вы ссылаетесь. Чтобы сделать это, необходимо будет использовать некоторый interop p/invoke вызовы. Смотрите на pinvoke.net для примера того, как сделать это и в каких дополнительных структурах Вы будете нуждаться.

0
ответ дан 27 November 2019 в 18:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: