경로가 유효한지 확인


110

나는 단지 궁금합니다. 주어진 경로가 유효한지 확인하는 방법을 찾고 있습니다. (참고 : 파일이 존재하는지 확인하고 싶지 않습니다! 경로의 유효성 만 증명하고 싶습니다. 파일이 해당 위치에 존재할 수있는 경우) .

문제는 .Net API에서 아무것도 찾을 수 없다는 것입니다. Windows가 지원하는 많은 형식과 위치로 인해 MS 네이티브를 사용하고 싶습니다.

함수는 다음에 대해 확인할 수 있어야하기 때문에 :

  • 상대 경로 (./)
  • 절대 경로 (c : \ tmp)
  • UNC 경로 (\ some-pc \ c $)
  • 전체 경로 1024 문자와 같은 NTFS 제한-경로를 초과하지 않으면 많은 내부 Windows 기능에서 파일에 액세스 할 수 없게됩니다. 탐색기로 이름을 바꾸는 것은 여전히 ​​작동합니다.
  • 볼륨 GUID 경로 : "\? \ Volume {GUID} \ somefile.foo

누구든지 이와 같은 기능이 있습니까?


답변:


58

시도해보십시오 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.

9
이 반환 거짓 @"foo\bar\baz"완벽하게 유효한 상대 경로입니다 ...
토마스 레베

5
토마스 : 어떤 UriKind를 지정 했습니까? Absolute, Relative 또는 AbsoluteOrRelative를 사용할 수 있습니다.
Dan Gøran Lunde 2013

1
UriKind를 Relative 또는 AbsoluteOrRelative로 사용하더라도 Thomas가 언급 한 것과 같은 상대 경로에서는 작동하지 않았습니다. 나는 대신 Patko의 대답을 사용했고 그것은 내 목적에 맞게 작동합니다.
JohnnyM 2014

1
공백이 제대로 인코딩되지 않았기 때문에 IsWellFormedUriString을 사용할 때 \\ computerName \ Dir Name With Spaces \ fileName과 같은 경로에서 예외가 발생한다는 것을 발견했습니다. Uri (string) 생성자를 유효성 검사로 사용할 수 있으므로 유효성 검사 전에 문자열을 올바르게 인코딩 할 필요가 없다는 것을 알았습니다.
quintessential5

3
완벽하게 미세한 파일 경로에 대해 false를 반환합니다.
Evgeni Petrov


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

7

아래 코드에 문제가 없었습니다. (상대 경로는 '/'또는 '\'로 시작해야합니다.)

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

그리고 이것은 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);

3

이 코드를 시도해 볼 수 있습니다.

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

모든 경우를 다룰 수 있을지 모르겠습니다 ...


2

내가 가장 가까운 것은 그것을 만들려고 시도하고 성공하는지 확인하는 것입니다.


2

여기에는 좋은 솔루션이 많이 있지만 경로가 기존 드라이브에 뿌리를두고 있는지 확인하는 방법은 없습니다 .

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

이 솔루션은 상대 경로를 고려 하지 않습니다 .


1

잘못된 문자를 가져 와서 System.IO.Path.GetInvalidPathChars();문자열 (디렉터리 경로)에 해당 문자가 포함 되어 있는지 확인하십시오.


3
이것은 완전히 유효하지 않습니다. "C : \ new.folder"는 "C : \ newfolder"동안 유효합니다. 아니다. '.' 경로 / 파일 이름에 유효한 문자이지만 uri 끝이 아닙니다.
claudekennilol 2013 년

0

4
"[...] 파일이 존재하는지 확인하고 싶지 않습니다!"
Stefan

3
유효한 경로가 아닌 기존 디렉토리에 대한 테스트 (적절한 권한이 주어지면 존재하거나 생성 될 수있는 위치)
Martijn

3
@Jason-파일을 확인하지 않고 포함 된 폴더 만 확인합니다.
markpsmith

8
그러나 유효한 디렉토리 경로는 여전히 존재할 수 없습니다.
Stefan

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

1
x1의 목적은 무엇입니까?
JayJay


-4

Path.IsPathRooted ()를 Path.GetInvalidFileNameChars ()와 함께 사용하여 경로가 중간 정도인지 확인할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.