2011-04-06 10 views
68

주어진 경로가 전체 경로인지 확인하는 방법이 있습니까? 지금 당장이 일을하고 있습니다 :주어진 전체 경로가 있는지 확인하십시오.

if (template.Contains(":\\")) //full path already given 
{ 
} 
else //calculate the path from local assembly 
{ 
} 

그러나 이것을 확인하는 더 세련된 방법이 있어야합니까?

답변

102

System.IO.Path.IsPathRooted을 사용해보세요. 또한 절대 경로의 경우 true을 반환합니다.

System.IO.Path.IsPathRooted(@"c:\foo"); // true 
System.IO.Path.IsPathRooted(@"\foo"); // true 
System.IO.Path.IsPathRooted("foo"); // false 

System.IO.Path.IsPathRooted(@"c:1\foo"); // surprisingly also true 
System.IO.Path.GetFullPath(@"c:1\foo");// returns "[current working directory]\1\foo" 
+6

초 예는 절대 경로 와서 어떻게? – om471987

+1

두 번째 경로는 절대 경로가 아니지만 루트 경로입니다. 선행 슬래시는 시스템의 루트를 나타냅니다. – detaylor

+1

@SmirkinGherkin 그래서 뿌리와 절대 경로의 차이점은 무엇입니까? –

0

난 당신이 전체 경로가 무엇을 의미하는지 정말 모르겠어요 (당신은 이후 루트에서 비 상대를 의미 예로부터 가정하지만), 음, 당신은 당신을 돕기 위해 Path 클래스를 사용할 수 있습니다 실제 파일 시스템 경로로 작업하기 때문에 대부분의 경우에 대비해야합니다.

14

는 UNC 경로뿐만 아니라 지역 것들에 대한

System.IO.Path.IsPathRooted(template) 

작품을보십시오.

예.

Path.IsPathRooted(@"\\MyServer\MyShare\MyDirectory") // returns true 
Path.IsPathRooted(@"C:\\MyDirectory") // returns true 
+5

Thnx로 관찰 될 수 있도록 포함되었지만 Smirkin은 처음이었고 하나의 응답만을 받아 들일 수 있습니다 ( – hs2d

10

이전 질문이지만 한 가지 더 적용 가능한 답변입니다. 로컬 경로에 포함 된 볼륨을 확인해야하는 경우는 다음과 같이 System.IO.Path.GetFullPath()를 사용할 수 있습니다

if (template == System.IO.Path.GetFullPath(template)) 
{ 
    ; //template is full path including volume or full UNC path 
} 
else 
{ 
    if (useCurrentPathAndVolume) 
     template = System.IO.Path.GetFullPath(template); 
    else 
     template = Assembly.GetExecutingAssembly().Location 
} 
+3

). 이것은 내가 필요로하는 것이었고, IsPathRooted '가 true를 반환 한 이후 원래의 질문에 더 가깝게 보인다. 상대 경로 (반드시 절대 경로는 아님) – bitcoder

+0

'GetFullPath'는 파일 시스템에 액세스하며 가능한 많은 예외를 throw 할 수 있습니다. 내 대답 (http://stackoverflow.com/a/35046453/704808)을 참고하여 대안을 찾아보십시오 – weir

11
Path.IsPathRooted(path) 
&& !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) 

위의 조건 :

  • 가하는
  • path의 형식이 유효하지 않은 경우 (예외를 throw하는 것이 아니라) 대부분 false을 반환합니다.
  • 은을 반환합니다. path는 OP가 제기 같은 시나리오에서 볼륨

포함 된 경우에만은 따라서 이전의 응답의 상태보다 더 적합 할 수있다. 위의 조건을 달리 :

  • path == System.IO.Path.GetFullPath(path) 오히려 이러한 시나리오에 false을 돌아보다 예외를 던졌습니다 : 시스템이 절대 경로를 검색 할 수 없습니다 이
    • 호출자가 필요한 권한
    • 이없는
    • 경로에 볼륨 식별자의 일부가 아닌 콜론 (":")이 포함되어 있습니다path 단일 디렉토리 분리로 시작하는 경우
    • 지정된 경로 또는 파일 이름이 시스템 정의 최대 길이를
  • System.IO.Path.IsPathRooted(path) 복귀 true 초과.

    public static bool IsFullPath(string path) { 
        return !String.IsNullOrWhiteSpace(path) 
         && path.IndexOfAny(System.IO.Path.GetInvalidPathChars().ToArray()) == -1 
         && Path.IsPathRooted(path) 
         && !Path.GetPathRoot(path).Equals(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal); 
    } 
    

    EDIT :

마지막으로, 여기에 나머지 가능한 예외 상기 조건을 래핑하는 방법이고, 또한이 차압 EM0는 C:과 같은 경로를 거꾸로 어드레싱 좋은 주석과 alternative answer했다 C:dir. 이러한 경로를 처리하는 방법을 결정할 수 있도록하려면 MSDN에서 자세히 살펴보십시오. ->Windows 데스크톱 응용 프로그램 -> ->데스크톱 기술 ->데이터 액세스 및 저장소 ->로컬 파일 시스템 - 파일, 경로 및 네임 스페이스 이름 지정>->만들기, 삭제, 그리고이 파일 유지 - 파일 관리 정보>->파일 관리 - >Fully Qualified vs. Relative Paths

파일을 조작하는 Windows API 함수의 경우 파일 이름은 종종 이 현재 디렉토리와 관련되어있을 수 있지만 일부 API는 완전한 정규 경로가 필요합니다. 항상 두 개의 백 슬래시 문자 ("\")로 시작하는 모든 형식의

  • UNC 이름을 : 그것은 다음 중 한 가지로 시작하지 않는 경우 파일 이름은 현재 디렉토리에 상대적입니다. 자세한 내용은 다음 절을 참조하십시오.
  • 백 슬래시가있는 디스크 지정자 (예 : "C : \"또는 "d : \").
  • 하나의 백 슬래시 (예 : "\ directory"또는 "\ file.txt"). 이것은 절대 경로라고도합니다.

파일 이름은 디스크 지정자로 시작하는 경우 만 백 슬래시 콜론 뒤에, 그것은 지정된 문자로 드라이브의 현재 디렉토리에 대한 상대 경로로 해석됩니다 없습니다. 현재 디렉토리는 에 따라 루트 디렉토리 일 수도 있고 그렇지 않을 수도 있습니다. 가장 최근의 "디렉토리 변경" 작업 중에 설정되었습니다.

  • 다음과 같이이 형식의 예는 "C를 : tmp.txt"TEMPDIR \ tmp.txt C 드라이브에 현재 디렉토리
  • "C에서"tmp.txt "라는 이름의 파일을 참조 "C 드라이브에 현재 디렉토리에 하위 디렉토리에 파일을 참조

[...] 위어의 대답에

+2

나는 이것이 잘못된 경로 때문에 던지지 않는 것을 좋아하지만, "C :"와 "C : dir"같은 경로는 현재 디렉토리를 사용하는 GetFullPath에 의해 해결됩니다. 그래서 그들은 그렇지 않습니다. 절대). 이들에 대해 거짓을 반환하는 답변 게시 됨 – EM0

+0

@ EM0 - 감사합니다. 방금 나에게 뭔가 가르쳐주었습니다. :) – weir

1

건물 :이 유효하지 않은 경로에 대한 throw하지 않습니다, 또한을 반환합니다. "C :", "C : dirname"및 "\ path"와 같은 경로의 경우입니다.

public static bool IsFullPath(string path) 
    { 
     if (string.IsNullOrWhiteSpace(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1 || !Path.IsPathRooted(path)) 
      return false; 

     var pathRoot = Path.GetPathRoot(path); 
     if (pathRoot.Length <= 2 && pathRoot != "/") // Accepts X:\ and \\UNC\PATH, rejects empty string, \ and X:, but accepts/to support Linux 
      return false; 

     return !(pathRoot == path && pathRoot.StartsWith("\\\\") && pathRoot.IndexOf('\\', 2) == -1); // A UNC server name without a share name (e.g "\\NAME") is invalid 
    } 

이렇게하면 Windows와 Linux에서 결과가 달라집니다. "/ path"는 Linux에서는 절대적이지만 Windows에서는 절대적이지 않습니다.

단위 테스트 :

[Test] 
    public void IsFullPath() 
    { 
     bool isWindows = Environment.OSVersion.Platform.ToString().StartsWith("Win"); // .NET Framework 
     // bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows); // .NET Core 

     // These are full paths on Windows, but not on Linux 
     TryIsFullPath(@"C:\dir\file.ext", isWindows); 
     TryIsFullPath(@"C:\dir\", isWindows); 
     TryIsFullPath(@"C:\dir", isWindows); 
     TryIsFullPath(@"C:\", isWindows); 
     TryIsFullPath(@"\\unc\share\dir\file.ext", isWindows); 
     TryIsFullPath(@"\\unc\share", isWindows); 

     // These are full paths on Linux, but not on Windows 
     TryIsFullPath(@"/some/file", !isWindows); 
     TryIsFullPath(@"/dir", !isWindows); 
     TryIsFullPath(@"/", !isWindows); 

     // Not full paths on either Windows or Linux 
     TryIsFullPath(@"file.ext", false); 
     TryIsFullPath(@"dir\file.ext", false); 
     TryIsFullPath(@"\dir\file.ext", false); 
     TryIsFullPath(@"C:", false); 
     TryIsFullPath(@"C:dir\file.ext", false); 
     TryIsFullPath(@"\dir", false); // An "absolute", but not "full" path 

     // Invalid on both Windows and Linux 
     TryIsFullPath(null, false, false); 
     TryIsFullPath("", false, false); 
     TryIsFullPath(" ", false, false); 
     TryIsFullPath(@"C:\inval|d", false, false); 
     TryIsFullPath(@"\\is_this_a_dir_or_a_hostname", false, false); 
    } 

    private static void TryIsFullPath(string path, bool expectedIsFull, bool expectedIsValid = true) 
    { 
     Assert.AreEqual(expectedIsFull, PathUtils.IsFullPath(path), "IsFullPath('" + path + "')"); 

     if (expectedIsFull) 
     { 
      Assert.AreEqual(path, Path.GetFullPath(path)); 
     } 
     else if (expectedIsValid) 
     { 
      Assert.AreNotEqual(path, Path.GetFullPath(path)); 
     } 
     else 
     { 
      Assert.That(() => Path.GetFullPath(path), Throws.Exception); 
     } 
    } 
+0

좋은 물건. 나는 https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#fully_qualified_vs._relative_paths가 Windows에서 경로가 * not * relative 인 것을 알았다. if 예를 들어, "\ directory"또는 "\ file.txt"와 같이 하나의 백 슬래시로 시작합니다. 이것은 절대 경로라고도합니다. '* – weir

+1

좋은 지적! 내 용어가 꺼진 것처럼 보입니다. "절대 경로"를 말했을 때 저는 MS가 "전체 경로"라고 부르는 것을 정말로 생각하고있었습니다. 나는 이름을 바꾸고 이것에 대한 테스트 케이스를 추가했다. – EM0

관련 문제