Làm cách nào để tìm thư mục mẹ trong C #?


85

Tôi sử dụng mã này để tìm thư mục gỡ lỗi

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

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

Làm cách nào tôi có thể tìm thấy thư mục mẹ như hình dưới đây?

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


15
Tại sao mọi người luôn sử dụng ToString () trên chuỗi?
Hogan

1
@Hogan, trong trường hợp tài sản thay đổi? : D
Shuifan

Câu trả lời:


126

Bạn có thể sử dụng System.IO.Directory.GetParent()để truy xuất thư mục mẹ của một thư mục nhất định.


21
nếu thư mục có dấu gạch chéo ở cuối, bạn phải gọi GetParent hai lần
Northben

2
Điều này dường như hoạt động trên những con đường tương đối (bất ngờ vui vẻ), nhưng sau đó không có cách nào để bạn lấy lại kết quả (bất ngờ không vui).
Adam

14
Thay vào đó, bạn có thể tránh vấn đề về dấu gạch chéo bằng cách sử dụng DirectoryInfo.Parent. vd new System.IO.DirectoryInfo("c:/path/to/somewhere//").Parent. @northben
mcNux

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

Xem BOL


35

Nếu bạn thêm ..\..vào đường dẫn hiện có của mình, hệ điều hành sẽ duyệt chính xác thư mục grand-cha.

Điều đó sẽ thực hiện công việc:

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

Nếu bạn duyệt qua đường dẫn đó, bạn sẽ duyệt qua thư mục grand-cha.


1
Điều đó trông đẹp mắt, nhưng không may là C: \ Users \ Masoud \ Documents \ Visual Studio 2008 \ Projects \ MyProj \ MyProj \ bin \ Debug \ .. \ ..
StuartQ

Có và nếu bạn duyệt theo đường dẫn đó, bạn sẽ duyệt qua thư mục cha-mẹ.
Lễ hội Pierre-Alain

Điểm hợp lý, tôi sẽ xóa phiếu phản đối, mặc dù tôi sẽ phải chỉnh sửa trong nhận xét của bạn để trả lại điểm.
StuartQ

3
Kết quả của "Path.Combine" có thể được chuyển qua "Path.GetFullPath" để làm sạch nó. Đó là để truy cập "C: \ Users \ Masoud \ Documents \ Visual Studio 2008 \ Projects \ MyProj \ MyProj"
Konstantin

1
Đây là cách tốt nhất để đi lên nhiều tầng lớp trong cây thư mục
Trung Lê

18

Tôi đã tìm thấy các biến thể System.IO.Path.Combine(myPath, "..")là dễ nhất và đáng tin cậy nhất. Thậm chí nhiều hơn thế nếu những gì northben nói là đúng, GetParent đó yêu cầu thêm một cuộc gọi nếu có dấu gạch chéo. Điều đó, đối với tôi, là không đáng tin cậy.

Path.Combine đảm bảo rằng bạn sẽ không bao giờ mắc phải những dấu gạch chéo.

..hoạt động giống hệt như ở mọi nơi khác trong Windows. Bạn có thể thêm bất kỳ số nào \..vào đường dẫn trong cmd hoặc explorer và nó sẽ hoạt động chính xác như tôi mô tả bên dưới.

Một số ..hành vi cơ bản :

  1. Nếu có tên tệp, ..sẽ cắt nó đi:

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

  1. Nếu đường dẫn là một thư mục, ..sẽ di chuyển lên một cấp:

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

  1. ..\.. tuân theo các quy tắc tương tự, hai lần liên tiếp:

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

  1. Và điều này có cùng tác dụng:

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


1
Tôi đồng ý rằng phương pháp này có lợi thế là hoạt động cho dù đường dẫn có dấu gạch chéo ngược ở cuối hay không. Và trong trường hợp bạn muốn có một con đường đơn giản mà không có dấu chấm trong nó, bạn có thể áp dụng Path.GetFullPath (() để kết quả.
RenniePet

1
Hai năm sau và tôi thấy mình trở lại đây một lần nữa. Lưu ý rằng Path.GetFullPath (() thường trả về một đường dẫn không có dấu gạch chéo ngược ở cuối, nhưng khi bạn vào thư mục gốc, ví dụ "E: \", thì sẽ có một dấu gạch chéo ngược.
RenniePet

Điều này không hoạt động, cả với .NET 4.7 và .NET Core 2.1: Path.Combine(@"D:\Grandparent\Parent\Child.txt", @"..")=D:\Grandparent\Parent\Child.txt\..
Métoule

Điều này không cắt ngắn tên tệp đối với tôi, ít nhất là trên MacOS thông qua Unity.
supergra

@ Métoule @supergra Tôi thấy sự nhầm lẫn. Path.Combinekhông cắt ngắn chính chuỗi. Đường dẫn , một khi được sử dụng để truy cập hệ thống tệp, có tác dụng dự kiến. Tuy nhiên, tôi đồng ý rằng điều này là không tối ưu. Xem câu trả lời gần đây hơn của tôi trên trang này để biết cách tiếp cận sửa đổi chuỗi thay vì cần hệ thống tệp để giải quyết đường dẫn.
Timo

11

Để nhận thư mục 'grandparent', hãy gọi Directory.GetParent () hai lần:

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

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

8

Directory.GetParentcó lẽ là một câu trả lời tốt hơn, nhưng cho đầy đủ có một phương pháp khác nhau mà mất chuỗi và trả về chuỗi: Path.GetDirectoryName.

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

1
Xin lưu ý bạn Path.GetDirectoryName không hoạt động tốt với các đường dẫn tương đối .. Directory.GetParent thì có.
nawfal

6

Như thế này:

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

Chúc may mắn!


1
myDirectory.Parent.ToString () trả về tên của thư mục con, không phải đường dẫn đầy đủ, chính xác những gì tôi đang tìm kiếm. Ngoài ra, thay vì làm Directory.GetParent (Directory.GetParent (str_directory) .ToString ()); như hiển thị ở trên, chỉ cần sử dụng myDirectory.parent.parent.ToString () sẽ nhận được 'grandparent'.
Weihui Guo

1
Tôi thấy phương pháp này là tốt nhất vì nó xử lý trường hợp đường dẫn thư mục của bạn có dấu gạch chéo. Trong khi nếu bạn sử dụng Directory.GetParent (), bạn phải gọi nó hai lần để loại bỏ các dấu gạch chéo và sau đó nhận được nguồn gốc thực sự.
Magnus


3

Để tránh các vấn đề với dấu \, hãy gọi nó theo cách sau:

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

1
Bạn có thể sử dụng TrimEndnếu bạn chỉ muốn loại bỏ dấu `'s . I'm not sure if a leading `là quan trọng trong các hệ điều hành khác.
Walter Stabosz

2

Để có được giải pháp của bạn, hãy thử cái này

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

2

Đây là cách phổ biến nhất - nó thực sự phụ thuộc vào chính xác những gì bạn đang làm: (Để giải thích, ví dụ dưới đây sẽ xóa 10 ký tự cuối cùng là những gì bạn yêu cầu, tuy nhiên, nếu có một số quy tắc kinh doanh đang thúc đẩy nhu cầu của bạn để tìm một vị trí cụ thể, bạn nên sử dụng chúng để truy xuất vị trí thư mục, không phải tìm vị trí của thứ khác và sửa đổi nó.)

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

Đầu tiên của bạn chỉ hoạt động nếu bạn biết rằng các ký tự cuối cùng là chính xác \bin\Debug , không có ` and no other path, so it's extraordinarily fragile. Your second doesn't work because môi trường theo sau Parent.
Joe White,

@Joe, tôi đã loại bỏ thứ 2. Nhưng tôi nghĩ đây là một câu trả lời hợp lệ, nếu đường dẫn luôn là \ bin \ debug thì nó sẽ hoạt động. Và như tôi đã nói OP thực sự nên xem BR là gì thúc đẩy nhu cầu về thư mục và sử dụng một cách tiếp cận khác (Tôi có thể sử dụng một mục cấu hình, nhưng tôi đoán ở BR và cấu trúc chương trình.)
Hogan,

Mặc dù không hoàn hảo và mỏng manh, nhưng đó là giải pháp duy nhất phù hợp với tôi. Đề xuất chỉnh sửa: "str_directory.length" phải là "str_directory.Length", chữ L viết thường không được chấp nhận.
OverMars 27/02/18

2

Không ai đã cung cấp một giải pháp có thể hoạt động đa dạng. Tôi biết nó không được hỏi cụ thể nhưng tôi đang làm việc trong môi trường linux nơi hầu hết các giải pháp (như tại thời điểm tôi đăng bài này) sẽ gặp lỗi.

Dấu phân tách đường dẫn mã hóa cứng (cũng như những thứ khác) sẽ gây ra lỗi trong bất kỳ thứ gì ngoại trừ hệ thống Windows.

Trong giải pháp ban đầu của tôi, tôi đã sử dụng:

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

Tuy nhiên, sau khi xem một số câu trả lời ở đây, tôi đã điều chỉnh nó thành:

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

2

Vì không có gì khác mà tôi đã tìm thấy giúp giải quyết vấn đề này theo cách thực sự chuẩn hóa, đây là một câu trả lời khác.

Lưu ý rằng một số câu trả lời cho các câu hỏi tương tự cố gắng sử dụng Uriloại, nhưng điều đó gặp khó khăn với dấu gạch chéo và không có dấu gạch chéo.

Câu trả lời khác của tôi trên trang này phù hợp với các hoạt động đặt hệ thống tệp hoạt động, nhưng nếu chúng ta muốn có đường dẫn được giải quyết ngay bây giờ (chẳng hạn như vì lý do so sánh) mà không cần thông qua hệ thống tệp C:/Temp/..C:/ sẽ được coi là khác. Nếu không đi qua hệ thống tệp, điều hướng theo cách đó không cung cấp cho chúng tôi một đường dẫn chuẩn hóa, có thể so sánh đúng cách.

Chúng ta có thể làm gì?

Chúng tôi sẽ xây dựng dựa trên khám phá sau:

Path.GetDirectoryName(path + "/") ?? ""sẽ cung cấp cho chúng tôi một đường dẫn thư mục một cách đáng tin cậy mà không có dấu gạch chéo .

  • Thêm dấu gạch chéo (as string, not as char) sẽ coi một nullđường dẫn giống như nó xử lý "".
  • GetDirectoryName sẽ không loại bỏ thành phần đường dẫn cuối cùng nhờ dấu gạch chéo được thêm vào.
  • GetDirectoryName sẽ bình thường hóa dấu gạch chéo và dấu chấm điều hướng.
  • Điều này bao gồm việc loại bỏ bất kỳ dấu gạch chéo nào.
  • Điều này bao gồm thu gọn ..bằng cách điều hướng lên.
  • GetDirectoryNamesẽ quay trở lại nullmột con đường trống mà chúng ta liên kết với nhau "".

Làm thế nào để chúng tôi sử dụng điều này?

Đầu tiên, chuẩn hóa đường dẫn đầu vào :

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

Sau đó, chúng tôi có thể lấy thư mục mẹ và chúng tôi có thể lặp lại thao tác này bất kỳ số lần nào để điều hướng thêm:

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

Lưu ý rằng chúng tôi chưa bao giờ chạm vào hệ thống tệp. Không có phần nào của đường dẫn cần tồn tại, như nếu chúng ta đã sử dụng DirectoryInfo.


1

Bạn không nên cố gắng làm điều đó. Environment.CurrentDirectory cung cấp cho bạn đường dẫn của thư mục thực thi. Điều này nhất quán bất kể tệp .exe ở đâu. Bạn không nên cố gắng truy cập một tệp được cho là ở vị trí tương đối ngược

Tôi khuyên bạn nên chuyển bất kỳ tài nguyên nào bạn muốn truy cập vào một vị trí địa phương. Của một thư mục hệ thống (chẳng hạn như AppData)


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

Nếu bạn xóa " bin\Debug\" trong thuộc tính Dự án -> Xây dựng -> Đường dẫn đầu ra, thì bạn có thể sử dụngAppDomain.CurrentDomain.BaseDirectory

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.