Проверьте правильность пути - PullRequest
95 голосов
/ 01 июня 2011

Мне просто интересно: я ищу способ проверить, является ли данный путь допустимым. (Примечание: я не хочу проверять, существует ли файл! Я только хочу подтвердить правильность пути - поэтому, если файл может существовать в этом месте) .

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

Так как функция должна иметь возможность проверять:

  • ОтносительныйПути (./)
  • Абсолютные пути (c: \ tmp)
  • UNC-пути (\ some-pc \ c $)
  • NTFS-ограничения, такие как полный путь1024 символа - если я не ошибаюсь, превышение пути сделает файл недоступным для многих внутренних функций Windows.Переименование его с помощью Explorer по-прежнему работает
  • Пути к GUID тома: "\? \ Volume {GUID} \ somefile.foo

У кого-нибудь есть такая функция?

Ответы [ 11 ]

56 голосов
/ 01 июня 2011

Попробуйте Uri.IsWellFormedUriString():

  • Неправильно экранирована строка.

    http://www.example.com/path???/file name
    
  • Строка является абсолютным Uri, который представляет неявный файл Uri.

    c:\\directory\filename
    
  • Строка является абсолютным URI, в котором отсутствует косая черта перед путем.

    file://c:/directory/filename
    
  • Строка содержит обратные косые черты без экранирования, даже если они рассматриваются как прямые косые черты.

    http:\\host/path/file
    
  • Строка представляет иерархический абсолютный Uri и не содержит ": //".

    www.example.com/path/file
    
  • Анализатор для Uri.Scheme указывает, что исходная строка не была правильно сформирована.

    The example depends on the scheme of the URI.
    
27 голосов
/ 01 июня 2011
6 голосов
/ 27 сентября 2014
private bool IsValidPath(string path)
{
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
    if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;
    string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
    strTheseAreInvalidFileNameChars += @":/?*" + "\"";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");
    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
        return false;

    DirectoryInfo dir = new DirectoryInfo(Path.GetFullPath(path));
    if (!dir.Exists)
        dir.Create();
    return true;
}
5 голосов
/ 16 февраля 2018

У меня не было проблем с кодом ниже. (Относительные пути должны начинаться с '/' или '\').

private bool IsValidPath(string path, bool allowRelativePaths = false)
{
    bool isValid = true;

    try
    {
        string fullPath = Path.GetFullPath(path);

        if (allowRelativePaths)
        {
            isValid = Path.IsPathRooted(path);
        }
        else
        {
            string root = Path.GetPathRoot(path);
            isValid = string.IsNullOrEmpty(root.Trim(new char[] { '\\', '/' })) == false;
        }
    }
    catch(Exception ex)
    {
        isValid = false;
    }

    return isValid;
}

Например, они вернут false:

IsValidPath("C:/abc*d");
IsValidPath("C:/abc?d");
IsValidPath("C:/abc\"d");
IsValidPath("C:/abc<d");
IsValidPath("C:/abc>d");
IsValidPath("C:/abc|d");
IsValidPath("C:/abc:d");
IsValidPath("");
IsValidPath("./abc");
IsValidPath("./abc", true);
IsValidPath("/abc");
IsValidPath("abc");
IsValidPath("abc", true);

И они вернули бы истину:

IsValidPath(@"C:\\abc");
IsValidPath(@"F:\FILES\");
IsValidPath(@"C:\\abc.docx\\defg.docx");
IsValidPath(@"C:/abc/defg");
IsValidPath(@"C:\\\//\/\\/\\\/abc/\/\/\/\///\\\//\defg");
IsValidPath(@"C:/abc/def~`!@#$%^&()_-+={[}];',.g");
IsValidPath(@"C:\\\\\abc////////defg");
IsValidPath(@"/abc", true);
IsValidPath(@"\abc", true);
2 голосов
/ 12 октября 2014

Вы можете попробовать этот код:

try
{
  Path.GetDirectoryName(myPath);
}
catch
{
  // Path is not valid
}

Я не уверен, что это охватывает все случаи ...

1 голос
/ 01 июня 2011

Получите недопустимые символы из System.IO.Path.GetInvalidPathChars(); и проверьте, содержит ли ваша строка (путь к каталогу) их или нет.

1 голос
/ 01 июня 2011

Самое близкое, к чему я пришел, - это попытаться создать его и посмотреть, удастся ли это.

1 голос
/ 01 июня 2011
0 голосов
/ 20 октября 2018

Здесь есть много хороших решений, но ни один из них не проверяет, укоренен ли путь в существующем диске , вот еще одно:

private bool IsValidPath(string path)
{
    // Check if the path is rooted in a driver
    if (path.Length < 3) return false;
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");
    if (!driveCheck.IsMatch(path.Substring(0, 3))) return false;

    // Check if such driver exists
    IEnumerable<string> allMachineDrivers = DriveInfo.GetDrives().Select(drive => drive.Name);
    if (!allMachineDrivers.Contains(path.Substring(0, 3))) return false;

    // Check if the rest of the path is valid
    string InvalidFileNameChars = new string(Path.GetInvalidPathChars());
    InvalidFileNameChars += @":/?*" + "\"";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(InvalidFileNameChars) + "]");
    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
        return false;
    if (path[path.Length - 1] == '.') return false;

    return true;
}

Это решение не учитывает относительные пути.

0 голосов
/ 31 октября 2016
private bool IsValidPath(string path)
{
    Regex driveCheck = new Regex(@"^[a-zA-Z]:\\$");

    if (string.IsNullOrWhiteSpace(path) || path.Length < 3)
    {
        return false;
    }

    if (!driveCheck.IsMatch(path.Substring(0, 3)))
    {
        return false;
    }

    var x1 = (path.Substring(3, path.Length - 3));
    string strTheseAreInvalidFileNameChars = new string(Path.GetInvalidPathChars());
    strTheseAreInvalidFileNameChars += @":?*";
    Regex containsABadCharacter = new Regex("[" + Regex.Escape(strTheseAreInvalidFileNameChars) + "]");

    if (containsABadCharacter.IsMatch(path.Substring(3, path.Length - 3)))
    {
        return false;
    }

    var driveLetterWithColonAndSlash = Path.GetPathRoot(path);

    if (!DriveInfo.GetDrives().Any(x => x.Name == driveLetterWithColonAndSlash))
    {
        return false;
    }

    return true;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...