115 votes

Comment créer un nom de fichier Windows valide à partir d'une chaîne quelconque?

J'ai une chaîne comme "Foo: Bar" que je veux utiliser comme nom de fichier, mais sous Windows, le caractère ":" n'est pas autorisé dans un nom de fichier.

Existe-t-il une méthode permettant de transformer "Foo: Bar" en quelque chose comme "Foo-Bar"?

181voto

Diego Jancic Points 2445

Essayez quelque chose comme ça:

 string fileName = "something";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
   fileName = fileName.Replace(c, '_');
}
 

Modifier:

Étant donné que GetInvalidFileNameChars() renverra 10 ou 15 caractères, il est préférable d’utiliser un StringBuilder au lieu d’une simple chaîne; la version originale prendra plus de temps et consomme plus de mémoire.

38voto

Phil Price Points 1441
fileName = fileName.Replace(":", "-")

Cependant ":" n'est pas le seul caractère illégal pour Windows. Vous aurez également à gérer:

/, \, :, *, ?, ", <, > and |

Ces sont contenus dans le Système.IO.Chemin d'accès.GetInvalidFileNameChars();

Aussi (sur Windows), "." ne peut pas être le seul caractère dans le nom de fichier (à la fois ".", "..", "...", et ainsi de suite ne sont pas valides). Soyez prudent lorsque vous nommez les fichiers avec ".", par exemple:

echo "test" > .test.

Va générer un fichier nommé ".test"

Enfin, si vous avez vraiment envie de faire les choses correctement, il y a quelques spéciales noms de fichier vous avez besoin pour regarder dehors pour. Sur Windows , vous ne pouvez pas créer de fichiers nommés:

CON, PRN, AUX, CLOCK$, NUL
COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.

20voto

Joseph Gabriel Points 3322

Ce n'est pas plus efficace, mais c'est plus amusant :)

     var fileName = "foo:bar";
    var invalidChars = System.IO.Path.GetInvalidFileNameChars();
    var cleanFileName = new string(fileName.Where(m => !invalidChars.Contains(m)).ToArray<char>());
 

16voto

Qwertie Points 5311

Si quelqu'un souhaite une version optimisée basée sur StringBuilder , utilisez ceci. Comprend l'astuce de rkagerer en option.

 static char[] _invalids;

/// <summary>Replaces characters in <c>text</c> that are not allowed in 
/// file names with the specified replacement character.</summary>
/// <param name="text">Text to make into a valid filename. The same string is returned if it is valid already.</param>
/// <param name="replacement">Replacement character, or null to simply remove bad characters.</param>
/// <param name="fancy">Whether to replace quotes and slashes with the non-ASCII characters " and ⁄.</param>
/// <returns>A string that can be used as a filename. If the output string would otherwise be empty, returns "_".</returns>
public static string MakeValidFileName(string text, char? replacement = '_', bool fancy = true)
{
    StringBuilder sb = new StringBuilder(text.Length);
    var invalids = _invalids ?? (_invalids = Path.GetInvalidFileNameChars());
    bool changed = false;
    for (int i = 0; i < text.Length; i++) {
        char c = text[i];
        if (invalids.Contains(c)) {
            var repl = replacement ?? '\0';
            if (fancy) {
                if (c == '"')       repl = '"'; // U+201D right double quotation mark
                else if (c == '\'') repl = '''; // U+2019 right single quotation mark
                else if (c == '/')  repl = '⁄'; // U+2044 fraction slash
            }
            if (repl != '\0')
                sb.Append(c);
        } else
            sb.Append(c);
    }
    if (sb.Length == 0)
        return "_";
    return changed ? sb.ToString() : text;
}
 

8voto

leggetter Points 7509

Diego a la bonne solution, mais il y a une très petite erreur. La version de string.Replace utilisée doit être string.Replace (char, char), il n'y a pas de chaîne.Replace (char, string)

Je ne peux pas modifier la réponse ou j'aurais simplement apporté le changement mineur.

Donc ça devrait être:

 string fileName = "something";
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
   fileName = fileName.Replace(c, '_');
}
 

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