@ Jo, bodoh itu benar! Juga, saya harus menunjukkan bahwa fungsi setara berfungsi dengan baik di Node.JS ... Menggelengkan kepala di Microsoft ...
NH.
2
@ zwcloud Untuk .NET Core / Standard, Path.Combine()terutama untuk kompatibilitas mundur (dengan perilaku yang ada). Anda akan lebih baik menggunakan Path.Join(): "Tidak seperti metode Combine, metode Join tidak berusaha untuk me-root path yang dikembalikan. (Yaitu, jika path2 adalah path absolut, metode Join tidak membuang path1 dan mengembalikan path2 sebagai Combine metode melakukannya.) "
Stajs
Jawaban:
205
Ini semacam pertanyaan filosofis (yang barangkali hanya Microsoft yang benar-benar dapat menjawab), karena ia melakukan persis seperti yang dikatakan dokumentasi.
Saya tidak tahu apa alasannya. Saya kira solusinya adalah menghapus (atau Trim) DirectorySeparatorChar dari awal jalur kedua; mungkin menulis metode Combine Anda sendiri yang melakukan itu dan kemudian memanggil Path.Combine ().
Melihat kode yang dibongkar (lihat posting saya), Anda benar.
Gulzar Nazim
7
Saya kira itu berfungsi seperti itu untuk memungkinkan akses mudah ke algoritma "saat ini bekerja".
BCS
Tampaknya berfungsi seperti melakukan urutan dari cd (component)baris perintah. Kedengarannya masuk akal bagi saya.
Adrian Ratnapala
11
Saya menggunakan trim ini untuk mendapatkan efek string yang diinginkan strFilePath = Path.Combine (basePath, otherPath.TrimStart (char baru [] {'\\', '/'}));
Matthew Lock
3
Saya memang mengubah kode kerja saya menjadi Path.Combinehanya untuk aman tetapi kemudian rusak .. Ini sangat bodoh :)
sotn
23
Ini adalah kode yang dibongkar dari .NET Reflector untuk metode Path.Combine. Periksa fungsi IsPathRooted. Jika path kedua di-root (dimulai dengan DirectorySeparatorChar), kembalikan path kedua apa adanya.
Saya juga berpikir bahwa cukup menjengkelkan bahwa penanganan string ini harus dilakukan secara manual, dan saya akan tertarik dengan alasan di balik ini.
Menurut saya ini adalah bug. Masalahnya adalah bahwa ada dua jenis jalur "absolut" yang berbeda. Path "d: \ mydir \ myfile.txt" adalah absolut, path "\ mydir \ myfile.txt" juga dianggap "absolut" meskipun tidak ada huruf drive. Perilaku yang benar, menurut saya, adalah dengan menambahkan huruf drive dari lintasan pertama ketika lintasan kedua dimulai dengan pemisah direktori (dan bukan lintasan UNC). Saya akan merekomendasikan untuk menulis fungsi helper wrapper Anda sendiri yang memiliki perilaku yang Anda inginkan jika Anda membutuhkannya.
Ini cocok dengan spek, tapi itu juga tidak seperti yang saya harapkan.
dthrasher
@ Jake Itu tidak menghindari perbaikan bug; itu beberapa orang berpikir panjang dan keras tentang bagaimana melakukan sesuatu, dan kemudian berpegang teguh pada apa pun yang mereka sepakati. Perhatikan juga perbedaan antara kerangka .Net (pustaka yang berisi Path.Combine) dan bahasa C #.
Jika salah satu jalur yang ditentukan adalah string dengan panjang nol, metode ini mengembalikan jalur lainnya. Jika path2 berisi path absolut, metode ini mengembalikan path2.
Beberapa menyarankan bahwa namespace harus bertabrakan, ... Saya pergi dengan Pathy, sebagai sedikit, dan untuk menghindari tabrakan namespace dengan System.IO.Path.
Ini berarti bahwa ketika Anda bergabung dengan jalur dengan garis miring sebelumnya, Anda sebenarnya bergabung dengan satu pangkalan dengan yang lain, dalam hal ini yang kedua mendapat prioritas.
Ini sebenarnya masuk akal, dalam beberapa cara, mengingat bagaimana (relatif) jalur diperlakukan biasanya:
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
Pertanyaan sebenarnya adalah: Mengapa path, yang dimulai dengan "\", dianggap "rooted"? Ini juga baru bagi saya, tetapi berfungsi seperti itu di Windows :
Pertama, saya mengevaluasi apakah Path2 dimulai dengan / dan jika itu benar, kembalikan Path2 tanpa karakter pertama. Jika tidak, kembalikan Path2 lengkap.
Ini berarti "direktori root drive saat ini". Dalam contoh Anda ini berarti folder "test" di direktori root drive saat ini. Jadi, ini bisa sama dengan "c: \ test".
Seperti disebutkan oleh Ryan itu melakukan persis apa yang dikatakan dokumentasi.
Dari waktu DOS, disk saat ini, dan jalur saat ini dibedakan.
\adalah path root, tetapi untuk CURRENT DISK.
Untuk setiap " disk " ada " jalur saat ini " yang terpisah . Jika Anda mengubah disk menggunakan cd D:Anda tidak mengubah jalur saat ini untuk D:\, tetapi untuk: "D: \ apa pun \ \ \ terakhir \ path \ diakses \ pada \ ini \ disk" ...
Jadi, di windows, literal @"\x"berarti: "CURRENTDISK: \ x". Oleh karena itu Path.Combine(@"C:\x", @"\y")memiliki parameter kedua path root, bukan relatif, meskipun tidak dalam disk yang dikenal ... Dan karena tidak diketahui yang mungkin menjadi «disk saat ini», python kembali "\\y".
Path.Combine()
terutama untuk kompatibilitas mundur (dengan perilaku yang ada). Anda akan lebih baik menggunakanPath.Join()
: "Tidak seperti metode Combine, metode Join tidak berusaha untuk me-root path yang dikembalikan. (Yaitu, jika path2 adalah path absolut, metode Join tidak membuang path1 dan mengembalikan path2 sebagai Combine metode melakukannya.) "Jawaban:
Ini semacam pertanyaan filosofis (yang barangkali hanya Microsoft yang benar-benar dapat menjawab), karena ia melakukan persis seperti yang dikatakan dokumentasi.
System.IO.Path.Combine
"Jika path2 berisi path absolut, metode ini mengembalikan path2."
Inilah metode Combine aktual dari sumber .NET. Anda dapat melihat bahwa ia memanggil CombineNoChecks , yang kemudian memanggil IsPathRooted di path2 dan mengembalikan jalur itu jika demikian:
Saya tidak tahu apa alasannya. Saya kira solusinya adalah menghapus (atau Trim) DirectorySeparatorChar dari awal jalur kedua; mungkin menulis metode Combine Anda sendiri yang melakukan itu dan kemudian memanggil Path.Combine ().
sumber
cd (component)
baris perintah. Kedengarannya masuk akal bagi saya.Path.Combine
hanya untuk aman tetapi kemudian rusak .. Ini sangat bodoh :)Ini adalah kode yang dibongkar dari .NET Reflector untuk metode Path.Combine. Periksa fungsi IsPathRooted. Jika path kedua di-root (dimulai dengan DirectorySeparatorChar), kembalikan path kedua apa adanya.
sumber
Saya ingin menyelesaikan masalah ini:
Tentu saja, semua jalur 1-9 harus berisi string yang setara pada akhirnya. Inilah metode PathCombine yang saya buat:
Saya juga berpikir bahwa cukup menjengkelkan bahwa penanganan string ini harus dilakukan secara manual, dan saya akan tertarik dengan alasan di balik ini.
sumber
Menurut saya ini adalah bug. Masalahnya adalah bahwa ada dua jenis jalur "absolut" yang berbeda. Path "d: \ mydir \ myfile.txt" adalah absolut, path "\ mydir \ myfile.txt" juga dianggap "absolut" meskipun tidak ada huruf drive. Perilaku yang benar, menurut saya, adalah dengan menambahkan huruf drive dari lintasan pertama ketika lintasan kedua dimulai dengan pemisah direktori (dan bukan lintasan UNC). Saya akan merekomendasikan untuk menulis fungsi helper wrapper Anda sendiri yang memiliki perilaku yang Anda inginkan jika Anda membutuhkannya.
sumber
Path.Combine
) dan bahasa C #.Dari MSDN :
Dalam contoh Anda, path2 mutlak.
sumber
Mengikuti saran Christian Graus dalam blog "Things I Hate about Microsoft" yang berjudul " Path.Combine pada dasarnya tidak berguna. ", Berikut adalah solusi saya:
Beberapa menyarankan bahwa namespace harus bertabrakan, ... Saya pergi dengan
Pathy
, sebagai sedikit, dan untuk menghindari tabrakan namespace denganSystem.IO.Path
.Sunting : Menambahkan pemeriksaan parameter nol
sumber
Kode ini harus melakukan trik:
sumber
Tidak mengetahui detail sebenarnya, tebakan saya adalah berusaha membuat bergabung seperti Anda mungkin bergabung dengan URI relatif. Sebagai contoh:
Ini berarti bahwa ketika Anda bergabung dengan jalur dengan garis miring sebelumnya, Anda sebenarnya bergabung dengan satu pangkalan dengan yang lain, dalam hal ini yang kedua mendapat prioritas.
sumber
Alasan:
URL kedua Anda dianggap sebagai jalur absolut,
Combine
Metode ini hanya akan mengembalikan jalur terakhir jika jalur terakhir adalah jalur absolut.Solusi: Hapus saja garis miring awal
/
Path kedua Anda (/SecondPath
hinggaSecondPath
). Maka itu berfungsi seperti yang Anda perkecualian.sumber
Ini sebenarnya masuk akal, dalam beberapa cara, mengingat bagaimana (relatif) jalur diperlakukan biasanya:
Pertanyaan sebenarnya adalah: Mengapa path, yang dimulai dengan
"\"
, dianggap "rooted"? Ini juga baru bagi saya, tetapi berfungsi seperti itu di Windows :sumber
Jika Anda ingin menggabungkan kedua jalur tanpa kehilangan jalur apa pun, Anda dapat menggunakan ini:
Atau dengan variabel:
Kedua kasus mengembalikan "C: \ test \ test".
Pertama, saya mengevaluasi apakah Path2 dimulai dengan / dan jika itu benar, kembalikan Path2 tanpa karakter pertama. Jika tidak, kembalikan Path2 lengkap.
sumber
== @"\"
cek denganPath.IsRooted()
panggilan karena"\"
bukan satu-satunya karakter yang perlu diperhitungkan.Kedua metode ini akan menyelamatkan Anda dari bergabung secara tidak sengaja dua string yang keduanya memiliki pembatas di dalamnya.
sumber
Ini berarti "direktori root drive saat ini". Dalam contoh Anda ini berarti folder "test" di direktori root drive saat ini. Jadi, ini bisa sama dengan "c: \ test".
sumber
Hapus slash awal ('\') di parameter kedua (path2) Path.Combine.
sumber
Saya menggunakan fungsi agregat untuk memaksa jalur menggabungkan seperti di bawah ini:
sumber
Seperti disebutkan oleh Ryan itu melakukan persis apa yang dikatakan dokumentasi.
Dari waktu DOS, disk saat ini, dan jalur saat ini dibedakan.
\
adalah path root, tetapi untuk CURRENT DISK.Untuk setiap " disk " ada " jalur saat ini " yang terpisah . Jika Anda mengubah disk menggunakan
cd D:
Anda tidak mengubah jalur saat ini untukD:\
, tetapi untuk: "D: \ apa pun \ \ \ terakhir \ path \ diakses \ pada \ ini \ disk" ...Jadi, di windows, literal
@"\x"
berarti: "CURRENTDISK: \ x". Oleh karena ituPath.Combine(@"C:\x", @"\y")
memiliki parameter kedua path root, bukan relatif, meskipun tidak dalam disk yang dikenal ... Dan karena tidak diketahui yang mungkin menjadi «disk saat ini», python kembali"\\y"
.sumber