.NET的安全/允许的文件名清理

是否有任何标准化/图书馆/testing的方式来取得一个任意的string,并以这种方式,它代表一个有效的文件名称?

滚动我自己的char-replace函数是很容易的,但是我想要一些更强大和更重要的东西。

Solutions Collecting From Web of ".NET的安全/允许的文件名清理"

这个问题并不像你想的那么简单。 不仅Path.GetInvalidFileNameChars中的字符是非法的,还有几个文件名,如“PRN”和“CON”,由Windows保留,不能创建。 任何以“。”结尾的名字 在Windows中也是非法的。 而且,还有各种长度限制。 在这里阅读完整列表。

如果这还不够,不同的文件系统有不同的限制,例如ISO 9660文件名不能以“ – ”开头,但可以包含它。

您可以使用Path.GetInvalidFileNameChars检查字符串中的哪些字符无效,并将其转换为有效的字符(如连字符),或者(如果需要双向转换),请使用转义标记(例如%他们的unicode代码的十六进制表示(我实际上曾经使用过这种技术,但是现在没有代码)。

编辑 :以防万一有人感兴趣,这里是代码。

 /// <summary> /// Escapes an object name so that it is a valid filename. /// </summary> /// <param name="fileName">Original object name.</param> /// <returns>Escaped name.</returns> /// <remarks> /// All characters that are not valid for a filename, plus "%" and ".", are converted into "%uuuu", where uuuu is the hexadecimal /// unicode representation of the character. /// </remarks> private string EscapeFilename(string fileName) { char[] invalidChars=Path.GetInvalidFileNameChars(); // Replace "%", then replace all other characters, then replace "." fileName=fileName.Replace("%", "%0025"); foreach(char invalidChar in invalidChars) { fileName=fileName.Replace(invalidChar.ToString(), string.Format("%{0,4:X}", Convert.ToInt16(invalidChar)).Replace(' ', '0')); } return fileName.Replace(".", "%002E"); } /// <summary> /// Unescapes an escaped file name so that the original object name is obtained. /// </summary> /// <param name="escapedName">Escaped object name (see the EscapeFilename method).</param> /// <returns>Unescaped (original) object name.</returns> public string UnescapeFilename(string escapedName) { //We need to temporarily replace %0025 with %! to prevent a name //originally containing escaped sequences to be unescaped incorrectly //(for example: ".%002E" once escaped is "%002E%0025002E". //If we don't do this temporary replace, it would be unescaped to "..") string unescapedName=escapedName.Replace("%0025", "%!"); Regex regex=new Regex("%(?<esc>[0-9A-Fa-f]{4})"); Match m=regex.Match(escapedName); while(m.Success) { foreach(Capture cap in m.Groups["esc"].Captures) unescapedName=unescapedName.Replace("%"+cap.Value, Convert.ToChar(int.Parse(cap.Value, NumberStyles.HexNumber)).ToString()); m=m.NextMatch(); } return unescapedName.Replace("%!", "%"); } 

你能提供更多关于“从任意字符串生成”的意思吗? 根据你的说法,这听起来像你问

有什么办法可以采取一个任意的字符串,并以这样的方式,它代表一个有效的文件名称?

如果是这样的话,那么没有一个我知道的标准功能。 但是,你可以使用下面的应该做的伎俩

 public static string MakeValidFileName(string name) { var invalid = Path.GetInvalidFileNameChars(); var builder = new StringBuilder(); foreach ( var cur in name ) { builder.Append(invalid.Contains(cur) ? '_' : cur); } return builder.ToString(); } 

你有没有看看Path.GetInvalidFileNameChars?

找到真正有用的.NET类第1部分 – System.IO.Path

只是为了它的乐趣,我在一行中做到了。

 Regex.Replace("http://codereview.stackexchange.com/questions/33851/how-can-i-improve-my-code/33857#33857", "[" + string.Join("", Path.GetInvalidFileNameChars().Select (p => p.ToString())) + "]", "_")