C#で親ディレクトリを見つけるにはどうすればよいですか?


86

このコードを使用してデバッグディレクトリを検索します

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"


16
なぜ人々は常に文字列にToString()を使用するのですか?
ホーガン

2
@ホーガン、プロパティが変更された場合は?:D
musefan 2011

回答:


128

System.IO.Directory.GetParent()特定のディレクトリの親ディレクトリを取得するために使用できます。


23
ディレクトリの末尾にスラッシュがある場合は、GetParentを2回呼び出す必要があります
northben 2013

3
これは相対パスで機能するように見えますが(嬉しい驚き)、結果を取り戻す方法がありません(不幸な驚き)。
アダム

15
代わりにを使用することで、末尾のスラッシュの問題を回避できますDirectoryInfo.Parent。例:new System.IO.DirectoryInfo("c:/path/to/somewhere//").Parent。@northben
mcNux 2018


35

..\..既存のパスに追加すると、オペレーティングシステムは祖父母フォルダを正しく参照します。

それは仕事をするはずです:

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

そのパスを参照すると、祖父母のディレクトリが参照されます。


1
見た目は良かったのですが、残念ながらC:\ Users \ Masoud \ Documents \ Visual Studio 2008 \ Projects \ MyProj \ MyProj \ bin \ Debug \ .. \ ..
StuartQ 2014

はい。そのパスを参照すると、親-親ディレクトリが参照されます。
Pierre-Alain Vigeant 2014

フェアポイント、私は反対票を削除しますが、ポイントを返すためにあなたのコメントを編集する必要があります。
StuartQ 2014

3
「Path.Combine」の結果を「Path.GetFullPath」に渡して、クリーンアップすることができます。これは、「C:\ Users \ Masoud \ Documents \ Visual Studio 2008 \ Projects \ MyProj \ MyProj」にアクセスすることです
Konstantin

1
これは、ディレクトリツリーのいくつかのレベルを上げるための最良の方法です
Trung Le

19

のバリアントがSystem.IO.Path.Combine(myPath, "..")最も簡単で信頼性が高いことがわかりました。ノースベンの言うことが真実である場合、末尾にスラッシュがある場合、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. ..\.. 同じルールに従い、2回続けて:

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年後、私は再びここに戻ってきました。。、その後、バックスラッシュがあります:「\ E」Path.GetFullPathは(()が正常に任意の末尾のバックスラッシュなしでパスを返しますが、あなたがルートディレクトリに立ち上がったときに、例えばあることに注意してください
RenniePet

これは仕事、どちらも.NET 4.7や.NETのコア2.1としません:Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..")=D:\Grandparent\Parent\Child.txt\..
Métoule

少なくともUnity経由のMacOSでは、これによってファイル名が切り捨てられることはありません。
スペルガ

@Métoule@ supergra混乱が見られます。Path.Combine文字列自体は切り捨てられません。パスは、ファイルシステムへのアクセスに使用されると、意図した効果があります。ただし、これは最適ではないことに同意します。パスを解決するためにファイルシステムを必要とせずに文字列を変更するアプローチについては、このページの最近の回答を参照してください。
ティモ


8

Directory.GetParentおそらくより良い答えですが、完全を期すために、文字列を受け取り、文字列を返す別のメソッドがありますPath.GetDirectoryName

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

1
Path.GetDirectoryNameは相対パスではうまく機能しません。Directory.GetParentは機能します。
nawfal 2017年

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 2017

1
この方法は、ディレクトリパスの末尾にスラッシュがある場合を処理するため、最適です。一方、Directory.GetParent()を使用する場合は、それを2回呼び出してスラッシュを削除してから、実際の親を取得する必要があります。
マグナス


3

末尾の\の問題を回避するには、次のように呼び出します。

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

1
他のOSで重要なTrimEnd末尾の`'s . I'm not sure if a leading `のみを削除する場合に使用できます。
WalterStabosz18年

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プロパティがないことがわかっている場合にのみ機能します。
ジョーホワイト

@ジョー、私は2番目を削除しました。しかし、これは有効な答えだと思います。パスが常に\ bin \ debugであれば、機能します。そして、私が言ったように、OPは、ディレクトリの必要性を促進するBRが何であるかを実際に調べ、別のアプローチを使用する必要があります(おそらく構成エントリを使用しますが、BRとプログラム構造を推測しています)
ホーガン

完璧で壊れやすいわけではありませんが、それが私のために働いた唯一の解決策です。推奨される編集:「str_directory.length」は「str_directory.Length」である必要があります。小文字のLは使用できません。
OverMars 2018

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 + "/") ?? ""末尾にスラッシュを付けずにディレクトリパスを確実に提供します。

  • スラッシュを追加すると(としてstringはなく、として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);

ファイルシステムには触れたことがないことに注意してください。を使用した場合のように、パスの一部が存在する必要はありません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.