C # Sanitize File Name

Ich habe kürzlich eine Reihe von MP3s von verschiedenen Orten in ein Repository verschoben. Ich habe die neuen Dateinamen mit Hilfe der ID3-Tags erstellt (danke, TagLib-Sharp!) Und festgestellt, dass ich ein @ erhaltSystem.NotSupportedException:

"Das angegebene Pfadformat wird nicht unterstützt."

Dies wurde generiert von entwederFile.Copy() oderDirectory.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;
}

u meiner Überraschung bekam ich weiterhin Ausnahmen. Es stellte sich heraus, dass ':' nicht in der Menge von @ enthalten isPath.GetInvalidPathChars(), weil es in einem Pfadstamm gültig ist. Ich nehme an, das macht Sinn - aber das muss ein ziemlich verbreitetes Problem sein. Hat jemand einen Kurzcode, der einen Pfad bereinigt? Am gründlichsten habe ich mir das ausgedacht, aber es fühlt sich an, als wäre es wahrscheinlich übertrieben.

    // 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());
    }

Jede Verbesserung, um diese Funktion schneller und weniger barock zu machen, wäre sehr willkommen.

Antworten auf die Frage(24)

Ihre Antwort auf die Frage