C #에서 부모 디렉터리를 찾으려면 어떻게합니까?


85

이 코드를 사용하여 디버그 디렉토리를 찾습니다.

public string str_directory = Environment.CurrentDirectory.ToString();

"C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj\\bin\\Debug"

아래와 같이 상위 폴더를 어떻게 찾을 수 있습니까?

"C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj"


15
사람들은 왜 항상 문자열에 ToString ()을 사용합니까?
Hogan

1
@Hogan, 속성이 변경되는 경우? : D
musefan 2011-07-29

답변:


126

System.IO.Directory.GetParent()주어진 디렉토리의 상위 디렉토리를 검색하는 데 사용할 수 있습니다 .


21
디렉토리 뒤에 슬래시가 있으면 GetParent를 두 번 호출해야합니다
northben 2013

2
이것은 상대 경로에서 작동하는 것처럼 보이지만 (행복한 놀라움) 결과를 되돌릴 방법이 없습니다 (행복한 놀라움).
Adam

14
대신을 사용하여 후행 슬래시 문제를 피할 수 있습니다 DirectoryInfo.Parent. 예 : new System.IO.DirectoryInfo("c:/path/to/somewhere//").Parent. @northben
mcNux

46
string parent = System.IO.Directory.GetParent(str_directory).FullName;

BOL 참조


35

..\..기존 경로에 추가 하면 운영 체제가 상위 상위 폴더를 올바르게 검색합니다.

이 작업을 수행해야합니다.

System.IO.Path.Combine("C:\\Users\\Masoud\\Documents\\Visual Studio 2008\\Projects\\MyProj\\MyProj\\bin\\Debug", @"..\..");

해당 경로를 찾아 보면 상위 디렉토리를 찾아 볼 것입니다.


1
\ 사용자 \ 마수드 \ 문서 \ \ 프로젝트 \의 Myproj \의 Myproj \ 빈 \ 디버그 \ .. \ .. 2008 스튜디오 비주얼 : 그 모습 좋은,하지만 불행히도 C 제공
StuartQ

예. 해당 경로를 탐색하면 상위-부모 디렉토리를 탐색합니다.
Pierre-Alain Vigeant 2014

요점을 되돌리려면 귀하의 의견을 편집해야하지만 반대표를 제거하겠습니다.
StuartQ 2014

3
"Path.Combine"의 결과는 "Path.GetFullPath"를 통해 전달되어 정리할 수 있습니다. 즉에 도착하는 것입니다 "C : \ 사용자 \ 마수드 \ 문서 \ 2008 스튜디오 비주얼 \ 프로젝트 \의 Myproj \의 Myproj"
콘스탄틴

1
이 디렉토리 트리의 여러 수준을 이동하는 가장 좋은 방법입니다
트룽 르

18

의 변형이 System.IO.Path.Combine(myPath, "..")가장 쉽고 가장 신뢰할 수 있음을 발견했습니다 . Northben의 말이 사실이라면 GetParent는 후행 슬래시가 있으면 추가 호출이 필요합니다. 나에게 그것은 신뢰할 수 없습니다.

Path.Combine은 슬래시가 잘못되지 않도록합니다.

..Windows의 다른 모든 곳에서와 똑같이 작동합니다. \..cmd 또는 explorer의 경로에 원하는 수를 추가 할 수 있으며 아래에서 설명한대로 정확하게 작동합니다.

몇 가지 기본 ..동작 :

  1. 파일 이름이 있으면 ..잘라냅니다.

Path.Combine(@"D:\Grandparent\Parent\Child.txt", "..") => D:\Grandparent\Parent\

  1. 경로가 디렉토리 인 ..경우 한 단계 위로 이동합니다.

Path.Combine(@"D:\Grandparent\Parent\", "..") => D:\Grandparent\

  1. ..\.. 두 번 연속으로 동일한 규칙을 따릅니다.

Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..\..")=> D:\Grandparent\ Path.Combine(@"D:\Grandparent\Parent\", @"..\..")=>D:\

  1. 그리고 이것은 똑같은 효과가 있습니다.

Path.Combine(@"D:\Grandparent\Parent\Child.txt", "..", "..")=> D:\Grandparent\ Path.Combine(@"D:\Grandparent\Parent\", "..", "..")=>D:\


1
이 방법은 경로에 백 슬래시가 있는지 여부에 관계없이 작동하는 이점이 있다는 데 동의합니다. 그리고 당신은 그 안에있는 점은 결과에 Path.GetFullPath을 (()에 적용 할 수없는 간단한 경로를 원하는 상황이다.
RenniePet

1
2 년 후 다시 이곳으로 돌아 왔습니다. Path.GetFullPath (()는 일반적으로 후행 백 슬래시없이 경로를 반환하지만 루트 디렉토리 (예 : "E : \")에
도달

.NET 4.7도 .NET Core 2.1에서도 작동하지 않습니다. Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..")=D:\Grandparent\Parent\Child.txt\..
Métoule

이것은 적어도 Unity를 통해 MacOS에서 파일 이름을 자르지 않습니다.
supergra

@ Métoule @supergra 나는 혼란을 본다. Path.Combine문자열 자체를 자르지 않습니다. 파일 시스템에 액세스하는 데 사용 된 경로 는 의도 한 효과를 갖습니다. 그러나 이것이 차선책이라는 데 동의합니다. 내보기 최근 답변을 수정 문자열 대신 파일 시스템을 필요로하는 경로를 해결한다는 접근 방식이 페이지를.
Timo

11

'조부모'디렉토리를 얻으려면 Directory.GetParent ()를 두 번 호출하십시오 .

var gparent = Directory.GetParent(Directory.GetParent(str_directory).ToString());

1
var gparent = Directory.GetParent(str_directory).Parent; // Cleaner?
JohnB 19

8

Directory.GetParent아마도 더 나은 대답 일 수 있지만 완전성을 위해 string을 취하고 string을 반환하는 다른 메서드가 있습니다 : Path.GetDirectoryName.

string parent = System.IO.Path.GetDirectoryName(str_directory);

1
Path.GetDirectoryName은 상대 경로와 잘 작동하지 않습니다. Directory.GetParent는 작동합니다.
nawfal

6

이렇게 :

System.IO.DirectoryInfo myDirectory = new DirectoryInfo(Environment.CurrentDirectory);
string parentDirectory = myDirectory.Parent.FullName;

행운을 빕니다!


1
myDirectory.Parent.ToString ()은 정확히 내가 찾고 있던 전체 경로가 아닌 하위 폴더의 이름을 반환합니다. 또한 Directory.GetParent (Directory.GetParent (str_directory) .ToString ()); 위와 같이 myDirectory.parent.parent.ToString ()을 사용하여 '조부모'를 가져옵니다.
Weihui Guo

1
이 방법은 디렉토리 경로에 슬래시가있는 경우를 처리하기 때문에 가장 좋습니다. Directory.GetParent ()를 사용하는 경우 슬래시를 제거하고 실제 부모를 가져 오기 위해 두 번 호출해야합니다.
Magnus


3

\ 뒤에 오는 문제를 피하려면 다음과 같이 호출하십시오.

  string ParentFolder =  Directory.GetParent( folder.Trim('\\')).FullName;

1
다른 OS에서 중요한` TrimEnd뒤에 오는 `'s . I'm not sure if a leading ` 를 제거하려는 경우에만 사용할 수 있습니다 .
Walter Stabosz

2

솔루션을 얻으려면 이것을 시도하십시오

string directory = System.IO.Directory.GetParent(System.IO.Directory.GetParent(Environment.CurrentDirectory).ToString()).ToString();

2

이것은 가장 일반적인 방법입니다. 정확히 무엇을하는지에 따라 다릅니다. (설명하기 위해 아래 예는 요청한 마지막 10자를 제거하지만 필요를 유발하는 비즈니스 규칙이있는 경우 특정 위치를 찾으려면 디렉토리 위치를 검색하는 데 사용해야하며 다른 위치를 찾아 수정하지 않아야합니다.)

// remove last 10 characters from a string
str_directory = str_directory.Substring(0,str_directory.Length-10);

첫 번째는 마지막 문자가 정확히 \bin\Debug 이고 후행이 없음 을 알고있는 경우에만 작동합니다. ` and no other path, so it's extraordinarily fragile. Your second doesn't work because Environment.CurrentDirectory`는 문자열이고 문자열에는 Parent속성 이 없습니다 .
Joe White

@Joe, 나는 두 번째를 제거했습니다. 그러나 경로가 항상 \ bin \ debug이면 이것이 유효한 대답이라고 생각합니다. 그리고 내가 말했듯이 OP는 디렉토리에 대한 요구를 유도하는 BR이 무엇인지 실제로보고 다른 접근 방식을 사용해야합니다 (아마도 구성 항목을 사용하지만 BR 및 프로그램 구조를 추측하고 있습니다.)
Hogan

완벽하고 연약하지는 않지만 나에게 도움이 된 유일한 솔루션입니다. 제안 된 편집 : "str_directory.length"는 "str_directory.Length"여야하며 소문자 L은 허용되지 않습니다.
OverMars

2

어느 누구도 교차 형식으로 작동하는 솔루션을 제공하지 않았습니다. 나는 그것이 특별히 요청되지 않았다는 것을 알고 있지만 대부분의 솔루션 (이 글을 게시 할 때)이 오류를 제공하는 Linux 환경에서 작업하고 있습니다.

하드 코딩 경로 구분 기호 (및 기타 사항)는 Windows 시스템 이외의 모든 항목에서 오류를 발생시킵니다.

내 원래 솔루션에서 다음을 사용했습니다.

char filesep = Path.DirectorySeparatorChar;
string datapath = $"..{filesep}..{filesep}";

그러나 여기에 몇 가지 답변을 본 후 다음과 같이 조정했습니다.

string datapath = Directory.GetParent(Directory.GetParent(Directory.GetCurrentDirectory()).FullName).FullName; 

2

내가 찾은 다른 것은 진정으로 정규화 된 방식으로 이것을 해결하는 데 도움이되지 않기 때문에 여기에 또 다른 대답이 있습니다.

유사한 질문에 대한 일부 답변은 Uri유형 을 사용하려고 시도 하지만 후행 슬래시와 후행 슬래시가없는 경우에도 어려움을 겪습니다.

다른 대답 이 페이지의 작업에 파일 시스템을 넣어 작업을 위해 작동하지만, 우리는 파일 시스템을 거치지 않고, 바로 지금 (예 : 비교 이유 등) 해결 된 경로를 갖고 싶어, 경우 C:/Temp/..C:/다른 간주됩니다. 파일 시스템을 거치지 않고 이러한 방식으로 탐색하면 정규화되고 적절하게 비교 가능한 경로가 제공되지 않습니다.

우리는 무엇을 할 수 있습니까?

우리는 다음 발견을 기반으로 구축 할 것입니다.

Path.GetDirectoryName(path + "/") ?? ""안정적으로 우리에게 디렉토리 경로를 제공 슬래시없이 .

  • 슬래시를 추가하면 (as string아니라 as char) null경로 가 처리되는 것과 동일하게 처리 ""됩니다.
  • GetDirectoryName 추가 된 슬래시 덕분에 마지막 경로 구성 요소를 버리지 않습니다.
  • GetDirectoryName 슬래시와 탐색 점을 정규화합니다.
  • 여기에는 후행 슬래시 제거가 포함됩니다.
  • 여기에는 ..위로 이동하여 축소 하는 것도 포함 됩니다.
  • GetDirectoryNamenull빈 경로로 돌아갑니다 "".

이것을 어떻게 사용합니까?

먼저 입력 경로를 정규화합니다 .

dirPath = Path.GetDirectoryName(dirPath + "/") ?? "";

그런 다음 상위 디렉토리를 가져올 수 있으며이 작업을 여러 번 반복하여 더 위로 이동할 수 있습니다.

// This is reliable if path results from this or the previous operation
path = Path.GetDirectoryName(path);

우리는 파일 시스템을 건드리지 않았습니다. .NET을 사용한 경우처럼 경로의 어떤 부분도 존재할 필요가 없습니다 DirectoryInfo.


1

그렇게하려고해서는 안됩니다. Environment.CurrentDirectory는 실행 가능한 디렉토리의 경로를 제공합니다. 이것은 .exe 파일의 위치에 관계없이 일관됩니다. 역 상대 위치에있는 것으로 간주되는 파일에 액세스하려고하면 안됩니다.

액세스하려는 리소스를 로컬 위치로 이동하는 것이 좋습니다. 시스템 디렉토리 (예 : AppData)


1
IO.Path.GetFullPath(@"..\..")

bin\Debug\프로젝트 속성-> 빌드-> 출력 경로에서 " " 를 지우면 다음을 사용할 수 있습니다.AppDomain.CurrentDomain.BaseDirectory

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