varias trenzado piedras perlas hacer faciles cristal con como collares collar cadenas cadena c# .net string filepath

trenzado - ¿Hay alguna manera de hacer que las cadenas de ruta de archivos sean seguras en c#?



como hacer collares faciles (12)

¿Por qué no convertir la cadena a un equivalente de Base64 como este?

string UnsafeFileName = "salmnas dlajhdla kjha;dmas''lkasn"; string SafeFileName = Convert.ToBase64String(Encoding.UTF8.GetBytes(UnsafeFileName));

Si quieres convertirlo de nuevo para que lo puedas leer:

UnsafeFileName = Encoding.UTF8.GetString(Convert.FromBase64String(SafeFileName));

Lo usé para guardar archivos PNG con un nombre único de una descripción aleatoria.

Mi programa tomará cadenas arbitrarias de internet y las usará para nombres de archivos. ¿Hay alguna manera simple de eliminar los caracteres incorrectos de estas cadenas o debo escribir una función personalizada para esto?


Aquí está la función que estoy usando ahora (gracias jcollum por el ejemplo C #):

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

Acabo de poner esto en una clase de "Ayudantes" para mayor comodidad.


Aquí está mi versión:

static string GetSafeFileName(string name, char replace = ''_'') { char[] invalids = Path.GetInvalidFileNameChars(); return new string(name.Select(c => invalids.Contains(c) ? replace : c).ToArray()); }

No estoy seguro de cómo se calcula el resultado de GetInvalidFileNameChars, pero el "Get" sugiere que no es trivial, así que guardo los resultados en caché. Además, esto solo atraviesa la cadena de entrada una vez en lugar de varias veces, como las soluciones anteriores que iteran sobre el conjunto de caracteres inválidos, reemplazándolos en la cadena de origen de a uno por vez. Además, me gustan las soluciones basadas en Where, pero prefiero reemplazar los caracteres inválidos en lugar de eliminarlos. Finalmente, mi reemplazo es exactamente un carácter para evitar la conversión de caracteres a cadenas a medida que repito sobre la cadena.

Digo todo eso sin hacer el perfil, este simplemente me "hizo sentir bien". :)


Esta pregunta se ha hecho many times before y, como se ha señalado muchas veces antes, IO.Path.GetInvalidFileNameChars no es adecuado.

En primer lugar, hay muchos nombres como PRN y CON que están reservados y no están permitidos para los nombres de archivo. Hay otros nombres no permitidos solo en la carpeta raíz. Los nombres que terminan en un período tampoco están permitidos.

En segundo lugar, hay una variedad de limitaciones de longitud. Lea la lista completa de NTFS here .

En tercer lugar, puede adjuntar a sistemas de archivos que tienen otras limitaciones. Por ejemplo, los nombres de archivo ISO 9660 no pueden comenzar con "-" pero pueden contenerlo.

En cuarto lugar, ¿qué haces si dos procesos "arbitrariamente" eligen el mismo nombre?

En general, el uso de nombres generados externamente para nombres de archivos es una mala idea. Sugiero generar sus propios nombres de archivos privados y almacenar nombres legibles por humanos internamente.


Esto es lo que acabo de agregar a la clase estática de ClipFlair ( http://clipflair.codeplex.com ) StringExtensions (proyecto UtilsSilverlight), en base a la información recopilada de los enlaces a las preguntas relacionadas con el publicadas por Dour High Arch arriba:

public static string ReplaceInvalidFileNameChars(this string s, string replacement = "") { return Regex.Replace(s, "[" + Regex.Escape(new String(System.IO.Path.GetInvalidPathChars())) + "]", replacement, //can even use a replacement string of any length RegexOptions.IgnoreCase); //not using System.IO.Path.InvalidPathChars (deprecated insecure API) }


Estoy de acuerdo con Grauenwolf y recomendaría mucho Path.GetInvalidFileNameChars()

Aquí está mi contribución de C #:

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

ps - esto es más críptico de lo que debería ser - estaba tratando de ser conciso.


Me parece que usar esto es rápido y fácil de entender:

<Extension()> Public Function MakeSafeFileName(FileName As String) As String Return FileName.Where(Function(x) Not IO.Path.GetInvalidFileNameChars.Contains(x)).ToArray End Function

Esto funciona porque una string es IEnumerable como una matriz char y hay una string constructor de cadena que toma una matriz char .


Para quitar los caracteres no válidos:

static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars(); // Builds a string out of valid chars var validFilename = new string(filename.Where(ch => !invalidFileNameChars.Contains(ch)).ToArray());

Para reemplazar caracteres inválidos:

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

Para reemplazar caracteres no válidos (y evitar posibles conflictos de nombres como 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 (Moves the Char into the letter range of unicode, starting at "A") var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? Convert.ToChar(invalidFileNameChars.IndexOf(ch) + 65) : ch).ToArray());


Si desea eliminar rápidamente todos los caracteres especiales que a veces son más legibles por el usuario para los nombres de los archivos, esto funciona muy bien:

string myCrazyName = "q`w^e!r@t#y$u%i^o&p*a(s)d_f-g+h=j{k}l|z:x/"c<v>b?n[m]q//w;e''r,t.y/u"; string safeName = Regex.Replace( myCrazyName, "/W", /*Matches any nonword character. Equivalent to ''[^A-Za-z0-9_]''*/ "", RegexOptions.IgnoreCase); // safeName == "qwertyuiopasd_fghjklzxcvbnmqwertyu"


Uf, lo odio cuando las personas intentan adivinar qué caracteres son válidos. Además de ser completamente no portátil (siempre pensando en Mono), los dos comentarios anteriores perdieron más de 25 caracteres no válidos.

''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


private void textBoxFileName_KeyPress(object sender, KeyPressEventArgs e) { e.Handled = CheckFileNameSafeCharacters(e); } /// <summary> /// This is a good function for making sure that a user who is naming a file uses proper characters /// </summary> /// <param name="e"></param> /// <returns></returns> internal static bool CheckFileNameSafeCharacters(System.Windows.Forms.KeyPressEventArgs e) { if (e.KeyChar.Equals(24) || e.KeyChar.Equals(3) || e.KeyChar.Equals(22) || e.KeyChar.Equals(26) || e.KeyChar.Equals(25))//Control-X, C, V, Z and Y return false; if (e.KeyChar.Equals(''/b''))//backspace return false; char[] charArray = Path.GetInvalidFileNameChars(); if (charArray.Contains(e.KeyChar)) return true;//Stop the character from being entered into the control since it is non-numerical else return false; }


static class Utils { public static string MakeFileSystemSafe(this string s) { return new string(s.Where(IsFileSystemSafe).ToArray()); } public static bool IsFileSystemSafe(char c) { return !Path.GetInvalidFileNameChars().Contains(c); } }