Recentemente ho spostato un sacco di MP3 da varie posizioni in un repository. Stavo costruendo i nuovi nomi di file usando i tag ID3 (grazie, TagLib-Sharp!), E ho notato che stavo ottenendo un System.NotSupportedException
:
"Il formato del percorso specificato non è supportato."
Questo è stato generato da File.Copy()
o Directory.CreateDirectory()
.
Non ci volle molto per capire che i miei nomi di file dovevano essere disinfettati. Quindi ho fatto la cosa ovvia:
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;
}
Con mia sorpresa, ho continuato a ricevere eccezioni. Si è scoperto che ':' non è nell'insieme di Path.GetInvalidPathChars()
, perché è valido in una radice del percorso. Suppongo che abbia un senso, ma questo deve essere un problema piuttosto comune. Qualcuno ha qualche codice breve che sanifica un percorso? Il più approfondito che ho pensato a questo, ma sembra che sia probabilmente eccessivo.
// 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());
}
Qualsiasi miglioramento per rendere questa funzione più veloce e meno barocca sarebbe molto apprezzato.