C# 从文件名(或目录、文件夹、文件)中删除无效(不允许、错误)字符

C# 从文件名(或目录、文件夹、文件)中删除无效(不允许、错误)字符,c#,asp.net,.net,C#,Asp.net,.net,我写了这个小方法来实现主题中的目标,但是,有没有更有效(更简单)的方法来实现这个目标?我希望这能帮助像我一样寻找这个的人 var fileName = new System.Text.StringBuilder(); fileName.Append("*Bad/\ :, Filename,? "); // get rid of invalid chars while (fileName.ToString().IndexOfAny(System.IO.Path.GetInvalidFileName

我写了这个小方法来实现主题中的目标,但是,有没有更有效(更简单)的方法来实现这个目标?我希望这能帮助像我一样寻找这个的人

var fileName = new System.Text.StringBuilder();
fileName.Append("*Bad/\ :, Filename,? ");
// get rid of invalid chars
while (fileName.ToString().IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) > -1)
{
    fileName = fileName.Remove(fileName.ToString().IndexOfAny(System.IO.Path.GetInvalidFileNameChars()), 1);
}

尝试以下方法

public string MakeValidFileName(string name) {
  var builder = new StringBuilder();
  var invalid = System.IO.Path.GetInvalidFileNameChars();
  foreach ( var cur in name ) {
    if ( !invalid.Contains(cur) ) {
      builder.Append(cur);
    }
  }
  return builder.ToString();
}
如果你在说“简单”时想要“简洁”:

public string StripInvalidChars(string filename) {
  return new String(
    filename.Except(System.IO.Path.GetInvalidFileNameChars()).ToArray()
  );
}

也就是说,我同意JaredPar的解决方案。它可能更容易阅读(取决于味道、背景),我的直觉是它更高效(尽管我不确定从有限长度的文件名中剥离这十几个无效字符的效率)和他使用的StringBuilder()似乎非常适合您的示例。

与.NET 4兼容的另一种方法。请参阅上面我的评论,解释这一需求

public static string ScrubFileName(string value)
{
   var sb = new StringBuilder(value);
   foreach (char item in Path.GetInvalidFileNameChars())
   {
      sb.Replace(item.ToString(), "");
   }
   return sb.ToString();
}

我知道这已经有几年历史了,但这里有另一个解决方案供参考

public string GetSafeFilename(string filename)
{

    return string.Join("_", filename.Split(Path.GetInvalidFileNameChars()));

}

我不相信Except方法能满足您的要求。它对复制品不起作用。“[Except]方法返回第一个元素中第二个没有出现的元素。它也不会返回第二个元素中第一个没有出现的元素。”via@ChronoPositron:启发我:问题出在哪里?我想要“第一个元素中不出现在第二个元素中的那些元素”(即不无效的字符)。我不想要“那些在第二个元素中没有出现在第一个元素中的元素”(即不存在的无效字符)。@Bejamin Podszun:问题是,Except作为一个集合操作工作。例如,如果我将“aaabbb.txt”(这是一个有效的文件名)传递给您的函数,则结果值为“ab.tx”。它只保留每个字母的第一次出现,这使得它删除的不仅仅是无效字符;它改变了函数的预期结果。@chronopositon:哇,你现在明白我的意思了。之前我缺少“set”部分,当我使用OP的testdata在LINQPad中快速测试时,我只注意到删除的无效字符(good),而不是缺少的有效元素(bad)。对不起,我的速度太慢了,谢谢你给我启发。你能编辑你的帖子并添加一个警告吗?在.NET 4中,无效的.Contains(cur)似乎对我不起作用。收到消息“此处无法访问私有方法”。提出了下面发布的另一个示例。将using System.Linq添加到顶部。-1感谢几年后没有使用
StringBuilder
,但无论如何,这是一个非常聪明的解决方案。从2014年起,仍然是我要使用的,而不是Regex.Replace=戴普。最佳解决方案。它还表明阅读整个线程(以及回答旧问题)是值得的。谢谢,Ceres。@Rob
GetInvalidFileNameChars()
包含“\”和“/”。此例程假定您只传递文件名。如果要检查文件路径的一部分,可以使用
path.GetInvalidPathChars()
。我将此用作扩展方法的基础。