@Joe, głupi ma rację! Muszę też zaznaczyć, że równoważna funkcja działa dobrze w Node.JS ... Kręcąc głową w Microsoft ...
NH.
2
@zwcloud Dla platformy .NET Core / Standard Path.Combine()służy głównie do kompatybilności wstecznej (z istniejącym zachowaniem). Lepiej byłoby użyć Path.Join(): „W przeciwieństwie do metody Łączenia, metoda łączenia nie próbuje zrootować zwróconej ścieżki. (To znaczy, jeśli ścieżka2 jest ścieżką bezwzględną, metoda łączenia nie odrzuca ścieżki 1 i zwraca ścieżkę 2 jako Łączenie metoda robi.) ”
Stajs
Odpowiedzi:
205
Jest to rodzaj filozoficznego pytania (na które być może tylko Microsoft może naprawdę odpowiedzieć), ponieważ robi dokładnie to, co mówi dokumentacja.
Nie wiem, jakie jest uzasadnienie. Myślę, że rozwiązaniem jest usunięcie (lub przycięcie) DirectorySeparatorChar od początku drugiej ścieżki; może napisz własną metodę Combine, która to robi, a następnie wywołuje Path.Combine ().
Patrząc na zdemontowany kod (sprawdź mój post), masz rację.
Gulzar Nazim
7
Sądzę, że działa w ten sposób, aby umożliwić łatwy dostęp do algorytmu „bieżący działający katalog”.
BCS,
Wygląda na to, że działa jak sekwencja cd (component)z wiersza poleceń. Brzmi dla mnie rozsądnie.
Adrian Ratnapala
11
Używam tego przycinania, aby uzyskać pożądany ciąg efektu strFilePath = Path.Combine (basePath, otherPath.TrimStart (new char [] {'\\', '/'}));
Matthew Lock
3
Path.Combine
Zmieniłem
23
To jest zdemontowany kod z .NET Reflector dla metody Path.Combine. Sprawdź funkcję IsPathRooted. Jeśli druga ścieżka jest zrootowana (zaczyna się od DirectorySeparatorChar), zwróć drugą ścieżkę taką, jaka jest.
Moim zdaniem jest to błąd. Problem polega na tym, że istnieją dwa różne rodzaje ścieżek „absolutnych”. Ścieżka „d: \ mydir \ myfile.txt” jest bezwzględna, ścieżka „\ mydir \ myfile.txt” również jest uważana za „bezwzględną”, mimo że brakuje jej litery dysku. Moim zdaniem poprawnym działaniem byłoby wstawienie litery dysku z pierwszej ścieżki, gdy druga ścieżka zaczyna się od separatora katalogów (i nie jest ścieżką UNC). Poleciłbym napisać własną funkcję opakowania pomocnika, która zachowa się tak, jak chcesz, jeśli jej potrzebujesz.
Jest zgodny ze specyfikacją, ale nie tego też bym się spodziewał.
dthrasher
@Jake To nie omija poprawki; to kilka osób zastanawiających się długo, jak coś zrobić, a następnie trzymających się tego, na co się zgodzą. Zwróć także uwagę na różnicę między frameworkiem .Net (biblioteką zawierającą Path.Combine) a językiem C #.
Jeśli jedna z określonych ścieżek jest łańcuchem o zerowej długości, ta metoda zwraca drugą ścieżkę. Jeśli ścieżka2 zawiera ścieżkę bezwzględną, ta metoda zwraca ścieżkę2.
Myślę, że przednie ukośniki powinny zostać wyjaśnione. Co to ma wspólnego z platformą .NET?
Peter Mortensen
3
Powód:
Twój drugi adres URL jest uważany za ścieżkę bezwzględną. CombineMetoda zwróci ostatnią ścieżkę tylko wtedy, gdy ostatnia ścieżka jest ścieżką bezwzględną.
Rozwiązanie: Wystarczy usunąć początkowy ukośnik /z drugiej ścieżki ( /SecondPathdo SecondPath). Następnie działa tak, jak wyjątek.
Ma to w pewnym sensie sens, biorąc pod uwagę, w jaki sposób (względne) ścieżki są zwykle traktowane:
stringGetFullPath(string path){string baseDir =@"C:\Users\Foo.Bar";returnPath.Combine(baseDir, path);}// Get full path for RELATIVE file pathGetFullPath("file.txt");// = C:\Users\Foo.Bar\file.txt// Get full path for ROOTED file pathGetFullPath(@"C:\Temp\file.txt");// = C:\Temp\file.txt
Prawdziwe pytanie brzmi: dlaczego ścieżki, które zaczynają się "\", są uważane za „zakorzenione”? To również było dla mnie nowe, ale działa tak w systemie Windows :
To \ oznacza „katalog główny bieżącego dysku”. W twoim przykładzie oznacza to folder „testowy” w katalogu głównym bieżącego dysku. Może to być więc równe „c: \ test”.
Jak wspomniał Ryan, robi dokładnie to, co mówi dokumentacja.
Od czasów DOS rozróżnia się bieżący dysk i bieżącą ścieżkę.
\jest ścieżką katalogu głównego, ale dla AKTUALNEGO DYSKU.
Dla każdego „ dysku ” istnieje osobna „ bieżąca ścieżka ”. Jeśli zmienisz dysk za pomocącd D: , nie zmienisz bieżącej ścieżki na D:\, ale na: „D: \ cokolwiek \ było \ ostatnią \ ścieżką \ dostępną \ na \ tym \ dysku” ...
Tak więc w systemie Windows literał @"\x"oznacza: „CURRENTDISK: \ x”. Dlatego Path.Combine(@"C:\x", @"\y")jako drugi parametr ma ścieżkę katalogu głównego, a nie krewnego, choć nie na znanym dysku ... A ponieważ nie wiadomo, który może być «bieżącym dyskiem», zwraca python "\\y".
Path.Combine()
służy głównie do kompatybilności wstecznej (z istniejącym zachowaniem). Lepiej byłoby użyćPath.Join()
: „W przeciwieństwie do metody Łączenia, metoda łączenia nie próbuje zrootować zwróconej ścieżki. (To znaczy, jeśli ścieżka2 jest ścieżką bezwzględną, metoda łączenia nie odrzuca ścieżki 1 i zwraca ścieżkę 2 jako Łączenie metoda robi.) ”Odpowiedzi:
Jest to rodzaj filozoficznego pytania (na które być może tylko Microsoft może naprawdę odpowiedzieć), ponieważ robi dokładnie to, co mówi dokumentacja.
System.IO.Path.Combine
„Jeśli ścieżka2 zawiera ścieżkę bezwzględną, ta metoda zwraca ścieżkę 2.”
Oto faktyczna metoda Combine ze źródła .NET. Możesz zobaczyć, że wywołuje on CombineNoChecks , który następnie wywołuje IsPathRooted na path2 i zwraca tę ścieżkę, jeśli tak:
Nie wiem, jakie jest uzasadnienie. Myślę, że rozwiązaniem jest usunięcie (lub przycięcie) DirectorySeparatorChar od początku drugiej ścieżki; może napisz własną metodę Combine, która to robi, a następnie wywołuje Path.Combine ().
źródło
cd (component)
z wiersza poleceń. Brzmi dla mnie rozsądnie.Path.Combine
To jest zdemontowany kod z .NET Reflector dla metody Path.Combine. Sprawdź funkcję IsPathRooted. Jeśli druga ścieżka jest zrootowana (zaczyna się od DirectorySeparatorChar), zwróć drugą ścieżkę taką, jaka jest.
źródło
Chciałem rozwiązać ten problem:
Oczywiście wszystkie ścieżki 1-9 powinny zawierać równoważny ciąg na końcu. Oto metoda PathCombine, którą wymyśliłem:
Myślę też, że to dość denerwujące, że ta obsługa łańcuchów musi być wykonywana ręcznie, i byłbym zainteresowany przyczyną tego.
źródło
Moim zdaniem jest to błąd. Problem polega na tym, że istnieją dwa różne rodzaje ścieżek „absolutnych”. Ścieżka „d: \ mydir \ myfile.txt” jest bezwzględna, ścieżka „\ mydir \ myfile.txt” również jest uważana za „bezwzględną”, mimo że brakuje jej litery dysku. Moim zdaniem poprawnym działaniem byłoby wstawienie litery dysku z pierwszej ścieżki, gdy druga ścieżka zaczyna się od separatora katalogów (i nie jest ścieżką UNC). Poleciłbym napisać własną funkcję opakowania pomocnika, która zachowa się tak, jak chcesz, jeśli jej potrzebujesz.
źródło
Path.Combine
) a językiem C #.Z MSDN :
W twoim przykładzie ścieżka 2 jest absolutna.
źródło
Zgodnie z radą Christiana Grausa w blogu „Things I Hate about Microsoft” zatytułowanym „ Path.Combine jest zasadniczo bezużyteczny ” . Oto moje rozwiązanie:
Niektórzy radzą, aby przestrzenie nazw kolidowały, ... Poszedłem
Pathy
trochę, aby uniknąć kolizji przestrzeni nazwSystem.IO.Path
.Edycja : Dodano sprawdzanie parametrów zerowych
źródło
Ten kod powinien załatwić sprawę:
źródło
Nie znając faktycznych szczegółów, domyślam się, że próbuje się połączyć, jakbyś mógł dołączyć względne identyfikatory URI. Na przykład:
Oznacza to, że łącząc ścieżkę z poprzednim ukośnikiem, faktycznie łączysz jedną bazę z drugą, w którym to przypadku druga ma pierwszeństwo.
źródło
Powód:
Twój drugi adres URL jest uważany za ścieżkę bezwzględną.
Combine
Metoda zwróci ostatnią ścieżkę tylko wtedy, gdy ostatnia ścieżka jest ścieżką bezwzględną.Rozwiązanie: Wystarczy usunąć początkowy ukośnik
/
z drugiej ścieżki (/SecondPath
doSecondPath
). Następnie działa tak, jak wyjątek.źródło
Ma to w pewnym sensie sens, biorąc pod uwagę, w jaki sposób (względne) ścieżki są zwykle traktowane:
Prawdziwe pytanie brzmi: dlaczego ścieżki, które zaczynają się
"\"
, są uważane za „zakorzenione”? To również było dla mnie nowe, ale działa tak w systemie Windows :źródło
Jeśli chcesz połączyć obie ścieżki bez utraty żadnej ścieżki, możesz użyć tego:
Lub ze zmiennymi:
Oba przypadki zwracają „C: \ test \ test”.
Najpierw oceniam, czy ścieżka 2 zaczyna się od / i czy to prawda, zwracam ścieżkę 2 bez pierwszego znaku. W przeciwnym razie zwróć pełną ścieżkę2.
źródło
== @"\"
czekPath.IsRooted()
rozmową, ponieważ"\"
nie jest to jedyna postać, którą należy uwzględnić.Te dwie metody powinny uchronić cię przed przypadkowym połączeniem dwóch ciągów, które zawierają ogranicznik.
źródło
To \ oznacza „katalog główny bieżącego dysku”. W twoim przykładzie oznacza to folder „testowy” w katalogu głównym bieżącego dysku. Może to być więc równe „c: \ test”.
źródło
Usuń początkowy ukośnik („\”) z drugiego parametru (ścieżka2) Path.Combine.
źródło
Użyłem funkcji agregującej, aby wymusić połączenie ścieżek, jak poniżej:
źródło
Jak wspomniał Ryan, robi dokładnie to, co mówi dokumentacja.
Od czasów DOS rozróżnia się bieżący dysk i bieżącą ścieżkę.
\
jest ścieżką katalogu głównego, ale dla AKTUALNEGO DYSKU.Dla każdego „ dysku ” istnieje osobna „ bieżąca ścieżka ”. Jeśli zmienisz dysk za pomocą
cd D:
, nie zmienisz bieżącej ścieżki naD:\
, ale na: „D: \ cokolwiek \ było \ ostatnią \ ścieżką \ dostępną \ na \ tym \ dysku” ...Tak więc w systemie Windows literał
@"\x"
oznacza: „CURRENTDISK: \ x”. DlategoPath.Combine(@"C:\x", @"\y")
jako drugi parametr ma ścieżkę katalogu głównego, a nie krewnego, choć nie na znanym dysku ... A ponieważ nie wiadomo, który może być «bieżącym dyskiem», zwraca python"\\y"
.źródło