Gần đây tôi đã chuyển một loạt các MP3 từ nhiều địa điểm khác nhau vào một kho lưu trữ. Tôi đã xây dựng tên tệp mới bằng cách sử dụng thẻ ID3 (cảm ơn, TagLib-Sharp!) Và tôi nhận thấy rằng tôi đang nhận được System.NotSupportedException
:
"Định dạng của đường dẫn đã cho không được hỗ trợ."
Điều này đã được tạo ra bởi một trong hai File.Copy()
hoặc Directory.CreateDirectory()
.
Không mất nhiều thời gian để nhận ra rằng tên tệp của tôi cần được vệ sinh. Vì vậy, tôi đã làm điều rõ ràng:
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;
}
Trước sự ngạc nhiên của tôi, tôi tiếp tục nhận được ngoại lệ. Hóa ra ':' không có trong tập hợp Path.GetInvalidPathChars()
, bởi vì nó hợp lệ trong một đường dẫn gốc. Tôi cho rằng điều đó có ý nghĩa - nhưng đây phải là một vấn đề khá phổ biến. Có ai có một số mã ngắn vệ sinh một con đường? Kỹ lưỡng nhất tôi đã đưa ra với điều này, nhưng cảm giác như nó có thể là quá mức cần thiết.
// 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());
}
Bất kỳ cải tiến để làm cho chức năng này nhanh hơn và ít baroque hơn sẽ được đánh giá cao.