111 votes

Existe-t-il un moyen de rendre les chaînes de chemin de fichiers sûres en c #?

Mon programme prendra des chaînes arbitraires sur Internet et les utilisera pour les noms de fichiers. Existe-t-il un moyen simple de supprimer les caractères incorrects de ces chaînes ou dois-je écrire une fonction personnalisée pour cela?

197voto

Jonathan Allen Points 23540

Ugh, je déteste quand les gens essaient de deviner quels personnages sont valides. En plus d'être complètement non-portable (en pensant toujours à Mono), les deux commentaires précédents manquaient plus de 25 caractères invalides.

 'Clean just a filename
Dim filename As String = "salmnas dlajhdla kjha;dmas'lkasn"
For Each c In IO.Path.GetInvalidFileNameChars
    filename = filename.Replace(c, "")
Next

'See also IO.Path.GetInvalidPathChars
 

45voto

Squirrel Points 555

Pour supprimer les caractères non valides:

 static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();

// Builds a string out of valid chars
var validFilename = new string(filename.Where(ch => !invalidFileNameChars.Contains(ch)).ToArray());
 

Pour remplacer les caractères non valides:

 static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();

// Builds a string out of valid chars and an _ for invalid ones
var validFilename = new string(filename.Select(ch => InvalidFileNameChars.Contains(ch) ? '_' : ch).ToArray());
 

Pour remplacer les caractères non valides (et éviter les conflits de noms potentiels tels que Hell * vs Hell $):

 static readonly IList<char> invalidFileNameChars = Path.GetInvalidFileNameChars();

// Builds a string out of valid chars and replaces invalid chars with a unique letter
var validFilename = new string(filename.Select(ch => InvalidFileNameChars.Contains(ch) ? Convert.ToChar(InvalidFileNameChars.IndexOf(ch) + 65) : ch).ToArray());
 

34voto

Dour High Arch Points 11896

Cette question a été posée de nombreuses fois avant et, comme l'a souligné à de nombreuses reprises avant, IO.Path.GetInvalidFileNameChars n'est pas suffisant.

Tout d'abord, il y a beaucoup de noms comme PRN et à la CON qui sont réservés et ne sont pas autorisées pour les noms de fichiers. Il y a d'autres noms pas seulement dans le dossier racine. Les noms qui se terminent dans un délai ne sont pas autorisés.

Deuxièmement, il existe une variété de limites de longueur. Voir la liste complète pour NTFS ici.

Troisièmement, vous pouvez attacher à des systèmes de fichiers qui ont d'autres limites. Par exemple, la norme ISO 9660 les noms de fichiers ne peut pas commencer par " -", mais elle peut contenir.

Quatrièmement, que faites-vous si deux processus "arbitrairement", choisissez le même nom?

En général, l'utilisation à l'extérieur-les noms générés pour les noms de fichiers est une mauvaise idée. Je suggère de générer votre propre privé noms de fichiers et de stockage des noms lisibles à l'interne.

22voto

Aaron Wagner Points 4556

Je suis d'accord avec Grauenwolf et recommande vivement le Path.GetInvalidFileNameChars()

Voici ma contribution en C #:

 string file = @"38?/.\}[+=n a882 a.a*/|n^%$ ad#(-))";
Array.ForEach(Path.GetInvalidFileNameChars(), 
      c => file = file.Replace(c.ToString(), String.Empty));
 

ps - c’est plus cryptique qu’il devrait être - j’essayais d’être concis.

13voto

sidewinderguy Points 883

Voici la fonction que j'utilise maintenant (merci jcollum pour l'exemple en C #):

 public static string MakeSafeFilename(string filename, char replaceChar)
{
    foreach (char c in System.IO.Path.GetInvalidFileNameChars())
    {
        filename = filename.Replace(c, replaceChar);
    }
    return filename;
}
 

Je viens de mettre cela dans une classe "Helpers" pour plus de commodité.

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