Ada bagian dalam aplikasi saya yang menampilkan jalur file yang dimuat oleh pengguna melalui OpenFileDialog. Butuh terlalu banyak ruang untuk menampilkan seluruh jalur, tapi saya tidak ingin hanya menampilkan nama file karena mungkin ambigu. Jadi saya lebih suka menunjukkan path file relatif ke direktori assembly / exe.
Misalnya, rakitan berada di C:\Program Files\Dummy Folder\MyProgram
dan file pada C:\Program Files\Dummy Folder\MyProgram\Data\datafile1.dat
saat itu saya ingin ditampilkan .\Data\datafile1.dat
. Jika file ada di C:\Program Files\Dummy Folder\datafile1.dat
, maka saya ingin..\datafile1.dat
. Tetapi jika file berada di direktori root atau 1 direktori di bawah root, maka tampilkan path lengkap.
Solusi apa yang akan Anda rekomendasikan? Regex?
Pada dasarnya saya ingin menampilkan info jalur file yang berguna tanpa mengambil terlalu banyak ruang layar.
EDIT: Hanya untuk memperjelas sedikit lagi. Tujuan dari solusi ini adalah untuk membantu pengguna atau saya sendiri mengetahui file mana yang saya muat terakhir dan kira-kira dari mana direktori itu berasal. Saya menggunakan kotak teks hanya baca untuk menampilkan jalan. Sebagian besar waktu, jalur file jauh lebih panjang daripada ruang tampilan kotak teks. Jalan itu seharusnya informatif tetapi tidak cukup penting untuk mengambil lebih banyak ruang layar.
Komentar Alex Brault bagus, begitu juga Jonathan Leffler. Fungsi Win32 yang disediakan oleh DavidK hanya membantu bagian dari masalah, bukan keseluruhan masalahnya, tetapi terima kasih. Sedangkan untuk solusi James Newton-King, saya akan mencobanya nanti saat saya bebas.
Jawaban:
.NET Core 2.0 telah
Path.GetRelativePath
, menggunakan ini.sumber
return relativeUri.ToString().Replace('/',Path.DirectorySeparatorChar);
c:\test
danc:\test\abc.txt
mengembalikantest\abc.txt
yang tidak relatif menurut saya. Saya harapkanabc.txt
Agak terlambat untuk pertanyaan, tetapi saya hanya perlu fitur ini juga. Saya setuju dengan DavidK bahwa karena ada fungsi API bawaan yang menyediakan ini, Anda harus menggunakannya. Inilah pembungkus yang dikelola untuk itu:
sumber
.NET Core 2.0 Jawaban
.NET Core 2.0 memiliki Path.GetRelativePath yang dapat digunakan seperti:
Dalam contoh di atas,
relativePath
variabelnya sama denganData\datafile1.dat
.Alternatif .NET Answer
Solusi @ Dave tidak berfungsi ketika path file tidak diakhiri dengan karakter garis miring (
/
) yang dapat terjadi jika path tersebut adalah path direktori. Solusi saya memperbaiki masalah itu dan juga menggunakanUri.UriSchemeFile
konstanta alih-alih hard coding"FILE"
.Jawaban Interop Windows
Ada Windows API yang disebut PathRelativePathToA yang dapat digunakan untuk menemukan jalur relatif. Harap perhatikan bahwa jalur file atau direktori yang Anda lewati untuk fungsi harus ada agar berfungsi.
sumber
AltDirectorySeparatorChar
adalah suatu kemungkinan, bukankah harusAppendDirectorySeparatorChar
memeriksanya juga?Ada fungsi Win32 (C ++) di shlwapi.dll yang melakukan persis seperti yang Anda inginkan:
PathRelativePathTo()
Saya tidak mengetahui cara apa pun untuk mengakses ini dari. NET selain ke P / Aktifkan saja.
sumber
shlwapi.dll
sekarang sudah tidak digunakan msdn.microsoft.com/en-us/library/windows/desktop/…"These functions are available through Windows XP Service Pack 2 (SP2) and Windows Server 2003. They might be altered or unavailable in subsequent versions of Windows."
Jika Anda menggunakan .NET Core 2.0,
Path.GetRelativePath()
tersedia dengan menyediakan fungsionalitas khusus ini:Jika tidak, untuk .NET framework penuh (per v4.7) merekomendasikan menggunakan salah satu jawaban yang disarankan lainnya.
sumber
Saya telah menggunakan ini di masa lalu.
sumber
Seperti yang ditunjukkan Alex Brault, terutama pada Windows, jalur absolut (dengan huruf drive dan semuanya) tidak ambigu dan seringkali lebih baik.
Bukankah seharusnya OpenFileDialog Anda menggunakan struktur tree-browser biasa?
Untuk mendapatkan beberapa nomenklatur, RefDir adalah direktori relatif yang Anda ingin tentukan path; itu AbsName adalah mutlak nama jalan yang Anda ingin peta; dan RelPath adalah jalur relatif yang dihasilkan.
Ambil yang pertama dari opsi ini yang cocok:
Untuk menggambarkan aturan terakhir (yang, tentu saja, sejauh ini paling kompleks), mulailah dengan:
Kemudian
Saat saya mengetik, DavidK menghasilkan jawaban yang menunjukkan bahwa Anda bukan orang pertama yang membutuhkan fitur ini dan ada fungsi standar untuk melakukan pekerjaan ini. Gunakan. Tetapi tidak ada salahnya untuk bisa memikirkan jalan Anda dari prinsip pertama, baik.
Kecuali bahwa sistem Unix tidak mendukung huruf drive (jadi semuanya selalu terletak di bawah direktori root yang sama, dan karena itu peluru pertama tidak relevan), teknik yang sama dapat digunakan pada Unix.
sumber
Masih jauh, tapi kelas System.Uri memiliki metode bernama MakeRelativeUri. Mungkin Anda bisa menggunakannya. Sungguh memalukan bahwa System.IO.Path tidak memiliki ini.
sumber
Seperti yang ditunjukkan di atas . NET Core 2.x memiliki implementasi
Path.GetRelativePath
.Kode di bawah ini diadaptasi dari sumber dan berfungsi baik dengan .NET 4.7.1 Framework.
sumber
Saya menggunakan ini:
sumber
Menggunakan:
sumber
path.Replace(rootPath.TrimEnd('\\') + "\\", "")
.Jika Anda yakin bahwa path absolut 2 Anda selalu relatif terhadap path absolut, cukup hapus karakter N pertama dari path2, di mana N adalah panjang path1.
sumber
Anda ingin menggunakan
CommonPath
metodeRelativePath
kelas ini . Setelah Anda memiliki jalur yang sama, cukup lepaskan dari jalur yang ingin Anda tampilkan.sumber
Saya akan membagi kedua jalur Anda di tingkat direktori. Dari sana, cari titik divergensi dan kembalilah ke folder assembly, tambahkan sebuah '../' setiap kali Anda melewati direktori.
Namun perlu diingat, bahwa jalur absolut bekerja di mana-mana dan biasanya lebih mudah dibaca daripada yang relatif. Saya pribadi tidak akan menunjukkan kepada pengguna jalur relatif kecuali jika itu mutlak diperlukan.
sumber
Jika Anda tahu bahwa toPath terkandung oleh fromPath maka Anda dapat membuatnya sederhana. Saya akan meninggalkan pernyataan untuk singkatnya.
sumber
Fungsi yang menggunakan URI mengembalikan "hampir" jalur relatif. Ini termasuk direktori yang secara langsung berisi file yang relatif ingin saya dapatkan.
Beberapa waktu lalu saya menulis fungsi sederhana yang mengembalikan path relatif folder atau file, dan bahkan jika itu ada di drive lain, itu termasuk huruf drive juga.
Silakan lihat:
sumber
Jika Anda memiliki kotak teks hanya baca, tidak bisakah Anda menjadikannya label dan mengatur AutoEllipsis = true?
atau ada posting dengan kode untuk membuat autoellipsis sendiri: (ini melakukannya untuk kotak, Anda perlu memberikan lebar untuk kotak teks sebagai gantinya. Tidak benar karena meretas sedikit lebih dari yang diperlukan , dan saya belum sempat menemukan di mana perhitungannya salah. akan cukup mudah untuk memodifikasi untuk menghapus bagian pertama dari direktori daripada yang terakhir jika Anda inginkan.
sumber
sumber
Ini seharusnya bekerja:
sumber
Cara dengan Uri tidak bekerja pada sistem linux / macOS. Path '/ var / www / root' tidak dapat dikonversi ke Uri. Cara yang lebih universal - lakukan semuanya dengan tangan.
PS: saya menggunakan "/" sebagai nilai default separator alih-alih Path.DirectorySeparatorChar, karena hasil dari metode ini digunakan sebagai uri di aplikasi saya.
sumber
ini milikku:
sumber
Main dengan sesuatu seperti:
Dan mengujinya
sumber
Di
ASP.NET Core 2
, jika Anda menginginkan jalur relatif kebin\Debug\netcoreapp2.2
Anda dapat menggunakan kombinasi berikut:sumber