开发者

Check whether a path is valid

开发者 https://www.devze.com 2023-03-10 02:38 出处:网络
I am just wondering: I am looking for a way to validate if a given path is valid. (Note: I do not want to check if a file is existing! I only want to proof the validity of the path - So if a file coul

I am just wondering: I am looking for a way to validate if a given path is valid. (Note: I do not want to check if a file is existing! I only want to proof the validity of the path - So if a file could possibly exists at the location).

Problem is, I can't find anything in the .Net API. Due to the many formats and locations that Windows supports, I'd rather use something MS-native.

Since the function should be able to check against:

  • Relative Paths (./)
  • Absolute Paths (c:\tmp)
  • UNC-Pathes (\some-pc\c$)
  • NTFS-Limitations like the full path 1024 chars - If I am not mistaken exceeding the path will make a file inaccessible for many internal Windows f开发者_如何学JAVAunctions. Renaming it with Explorer still works
  • Volume GUID Paths : "\?\Volume{GUID}\somefile.foo

Does anyone have a function like this?


Try Uri.IsWellFormedUriString():

  • The string is not correctly escaped.

      http://www.example.com/path???/file name
    
  • The string is an absolute Uri that represents an implicit file Uri.

      c:\\directory\filename
    
  • The string is an absolute URI that is missing a slash before the path.

      file://c:/directory/filename
    
  • The string contains unescaped backslashes even if they are treated as forward slashes.

      http:\\host/path/file
    
  • The string represents a hierarchical absolute Uri and does not contain "://".

      www.example.com/path/file
    
  • The parser for the Uri.Scheme indicates that the original string was not well-formed.

      The example depends on the scheme of the URI.
    


Or use the FileInfo as suggested in In C# check that filename is possibly valid (not that it exists).


I haven't had any problems with the code below. (Relative paths must start with '/' or '\').

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;
}

For example these would return 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);

And these would return 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);


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;
}


You can try this code:

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

I'm not sure it covers all the cases...


There are plenty of good solutions in here, but as none of then check if the path is rooted in an existing drive here's another one:

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;
}

This solution does not take relative paths into account.


The closest I have come is by trying to create it, and seeing if it succeeds.


Get the invalid chars from System.IO.Path.GetInvalidPathChars(); and check if your string (Directory path) contains those or not.


this accepts a path that could equate to a valid relative path too

string path = "yourPath";
bool pathIsValid = null;
try
{ 
    Path.GetFullPath(path);
    pathIsValid = true;
}
catch
{
    pathIsValid = false;
}


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;
}


Directory.Exists?


You could try using Path.IsPathRooted() in combination with Path.GetInvalidFileNameChars() to make sure the path is half-way okay.

0

精彩评论

暂无评论...
验证码 换一张
取 消