Baru-baru ini saya telah memindahkan banyak MP3 dari berbagai lokasi ke repositori. Saya telah membangun nama file baru menggunakan tag ID3 (terima kasih, TagLib-Sharp!), Dan saya perhatikan bahwa saya mendapatkan System.NotSupportedException
:
"Format jalur yang diberikan tidak didukung."
Ini dihasilkan oleh salah satu File.Copy()
atau Directory.CreateDirectory()
.
Tidak butuh waktu lama untuk menyadari bahwa nama file saya perlu disanitasi. Jadi saya melakukan hal yang jelas:
public static string SanitizePath_(string path, char replaceChar)
{
string dir = Path.GetDirectoryName(path);
foreach (char c in Path.GetInvalidPathChars())
dir = dir.Replace(c, replaceChar);
string name = Path.GetFileName(path);
foreach (char c in Path.GetInvalidFileNameChars())
name = name.Replace(c, replaceChar);
return dir + name;
}
Yang mengejutkan saya, saya terus mendapatkan pengecualian. Ternyata ':' tidak ada di set Path.GetInvalidPathChars()
, karena valid di root path. Saya kira itu masuk akal - tetapi ini harus menjadi masalah yang cukup umum. Adakah yang punya kode pendek yang membersihkan jalur? Yang paling teliti saya datang dengan ini, tapi rasanya seperti itu mungkin berlebihan.
// replaces invalid characters with replaceChar
public static string SanitizePath(string path, char replaceChar)
{
// construct a list of characters that can't show up in filenames.
// need to do this because ":" is not in InvalidPathChars
if (_BadChars == null)
{
_BadChars = new List<char>(Path.GetInvalidFileNameChars());
_BadChars.AddRange(Path.GetInvalidPathChars());
_BadChars = Utility.GetUnique<char>(_BadChars);
}
// remove root
string root = Path.GetPathRoot(path);
path = path.Remove(0, root.Length);
// split on the directory separator character. Need to do this
// because the separator is not valid in a filename.
List<string> parts = new List<string>(path.Split(new char[]{Path.DirectorySeparatorChar}));
// check each part to make sure it is valid.
for (int i = 0; i < parts.Count; i++)
{
string part = parts[i];
foreach (char c in _BadChars)
{
part = part.Replace(c, replaceChar);
}
parts[i] = part;
}
return root + Utility.Join(parts, Path.DirectorySeparatorChar.ToString());
}
Setiap perbaikan untuk membuat fungsi ini lebih cepat dan lebih sedikit barok akan sangat dihargai.
sumber
Jawaban:
Untuk membersihkan nama file Anda bisa melakukan ini
sumber
GetInvalidFileNameChars
tidak termasuk mereka. Itu tidak melempar pengecualian di windows, itu hanya menghapusnya, tetapi bisa menyebabkan perilaku yang tidak terduga jika Anda mengharapkan periode berada di sana. Saya memodifikasi regex untuk menangani case.
agar dianggap salah satu karakter yang tidak valid jika berada di akhir string.Solusi yang lebih pendek:
sumber
Berdasarkan jawaban Andre yang luar biasa tetapi dengan mempertimbangkan komentar Spud tentang kata-kata yang dipesan, saya membuat versi ini:
Dan ini adalah unit test saya
sumber
COM1
), Yang juga tidak diizinkan. Perbaikan yang disarankan adalah untuk mengubah reservedWordPattern ke"^{0}(\\.|$)"
dan string pengganti ke"_reservedWord_$1"
sumber
String.Concat(dirty...)
alih-alihJoin(String.Empty...
Saya menggunakan
System.IO.Path.GetInvalidFileNameChars()
metode ini untuk memeriksa karakter yang tidak valid dan saya tidak punya masalah.Saya menggunakan kode berikut:
sumber
Saya ingin mempertahankan karakter dengan cara tertentu, bukan hanya mengganti karakter dengan garis bawah.
Salah satu cara yang saya pikirkan adalah mengganti karakter dengan karakter yang mirip (dalam situasi saya), tidak mungkin digunakan sebagai karakter biasa. Jadi saya mengambil daftar karakter yang tidak valid dan menemukan look-a-likes.
Berikut ini adalah fungsi untuk menyandikan dan mendekode dengan look-a-likes.
Kode ini tidak termasuk daftar lengkap untuk semua karakter System.IO.Path.GetInvalidFileNameChars (). Jadi terserah Anda untuk memperpanjang atau menggunakan pengganti garis bawah untuk karakter yang tersisa.
Anda dapat memilih tampilan yang disukai. Saya menggunakan aplikasi Character Map di windows untuk memilih milik saya
%windir%\system32\charmap.exe
Saat saya melakukan penyesuaian melalui penemuan, saya akan memperbarui kode ini.
sumber
!"#$%&'()*+,-./:;<=>?@{|}~
atau bentuk lainnya seperti/
SOLIDUS dan `⁄` FRACTION SLASH yang dapat digunakan secara langsung dalam nama file tanpa masalahSaya pikir masalahnya adalah Anda pertama kali memanggil
Path.GetDirectoryName
string yang buruk. Jika ini memiliki karakter non-nama file di dalamnya, .Net tidak dapat menentukan bagian string mana yang merupakan direktori dan lemparan. Anda harus melakukan perbandingan string.Dengan asumsi itu hanya nama file yang buruk, bukan seluruh jalur, coba ini:
sumber
Saya telah sukses dengan ini di masa lalu.
Bagus, pendek dan statis :-)
sumber
ada banyak solusi yang bekerja di sini. hanya demi kelengkapan, berikut ini adalah pendekatan yang tidak menggunakan regex, tetapi menggunakan LINQ:
Juga, ini solusi yang sangat singkat;)
sumber
Berikut ini adalah metode ekstensi pemuatan malas yang efisien berdasarkan kode Andre:
sumber
Kode Anda akan lebih bersih jika Anda menambahkan direktori dan nama file bersama dan membersihkannya daripada membersihkannya secara mandiri. Sedangkan untuk membersihkan,: ambil saja karakter ke-2 dalam string. Jika sama dengan "replacechar", ganti dengan titik dua. Karena aplikasi ini untuk Anda gunakan sendiri, solusi seperti itu harus cukup memadai.
sumber
sumber