210 votes

C# aseptiser le nom du fichier

J'ai récemment fait évoluer un tas de fichiers Mp3 à partir de divers endroits dans un référentiel. J'avais été la construction de la nouvelle les noms de fichiers en utilisant les balises ID3 (merci, TagLib-Sharp!), et j'ai remarqué que je recevais un System.NotSupportedException:

"Le chemin du format n'est pas pris en charge."

Ceci a été généré par File.Copy() ou Directory.CreateDirectory().

Il n'a pas fallu longtemps pour réaliser que les noms de mes fichiers nécessaires pour être désinfectés. J'ai donc fait la chose la plus évidente:

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;
}

À ma grande surprise, j'ai continué à obtenir des exceptions. Il s'est avéré que les": "qui n'est pas dans l'ensemble de l' Path.GetInvalidPathChars(), parce qu'il est valable dans un chemin d'accès racine. Je suppose que c'est raisonnable, mais ce doit être un problème assez commun. Quelqu'un aurait-il quelques de code qui assainit un chemin d'accès? La plus approfondie, je suis venu avec cela, mais il se sent comme il est probablement excessif.

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

Toutes les améliorations pour rendre cette fonction plus rapide et moins baroque serait très apprécié.

369voto

Andre Points 2246

Pour nettoyer un nom de fichier, vous pourriez faire cela

178voto

DenNukem Points 3455

Une solution plus courte :

98voto

fiat Points 1542

Basé sur l’excellente réponse d’André, mais tenant commenter de compte Spud mots réservés, j’ai fait cette version :

Et voici mes tests unitaires

39voto

data Points 741
string clean = String.Join("", dirty.Split(Path.GetInvalidFileNameChars()));

2voto

Dour High Arch Points 11896

Je pense que le problème est que vous premier appel `` sur la chaîne de mauvaise. Si cela comporte des caractères non-filename, .net ne peut pas dire quelles parties de la chaîne sont jetés et les répertoires. Vous devrez chaîne de comparaisons.

En supposant que c’est seulement le nom du fichier qui est mauvais, pas le chemin entier, essayez ceci :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X