Ich habe kürzlich eine Reihe von MP3s von verschiedenen Orten in ein Repository verschoben. Ich hatte die neuen Dateinamen mit den ID3-Tags erstellt (danke, TagLib-Sharp!) Und bemerkte, dass ich Folgendes bekam System.NotSupportedException:
"Das Format des angegebenen Pfads wird nicht unterstützt."
Dies wurde entweder von File.Copy()oder generiert Directory.CreateDirectory().
Es dauerte nicht lange, bis mir klar wurde, dass meine Dateinamen bereinigt werden mussten. Also habe ich das Offensichtliche getan:
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;
}
Zu meiner Überraschung bekam ich weiterhin Ausnahmen. Es stellte sich heraus, dass ':' nicht in der Menge von enthalten ist Path.GetInvalidPathChars(), da es in einer Pfadwurzel gültig ist. Ich nehme an, das macht Sinn - aber das muss ein ziemlich häufiges Problem sein. Hat jemand einen Funktionscode, der einen Pfad bereinigt? Das gründlichste, was ich mir ausgedacht habe, aber es fühlt sich wahrscheinlich übertrieben an.
// 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());
}
Alle Verbesserungen, um diese Funktion schneller und weniger barock zu machen, wären sehr dankbar.