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.