我的节目将采取从互联网上任意的字符串,并将其用于文件名。有一个简单的方法来从这些字符串删除错误的字符或者我需要编写一个自定义功能呢?

有帮助吗?

解决方案

唉,我恨它,当人们试图猜测哪些字符有效。除了是完全非便携式(惦记单声道),无论是早期的意见错过了25个无效字符。

'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

其他提示

这个问题已经被问许多 前和以前一样多次指出的,IO.Path.GetInvalidFileNameChars是不够的。

首先,有喜欢的PRN和CON许多名字被保留,而不是允许的文件名。只有在根文件夹允许的其他名字不行。在一个周期结尾的名称也不允许。

其次,有各种各样的长度的限制。这里阅读NTFS 的完整列表。

三,你可以连接到有其他限制文件系统。例如,ISO 9660的文件名不能与开始“ - ”。但可以包含它

四,有什么事情,如果两个进程“随意”挑选相同的名字怎么办?

在一般情况下,使用外部生成的名称为文件名是一个好主意。我建议生成自己的私人文件名和内部存储人类可读的名字。

要剥离的无效字符:

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

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

要替换的无效字符:

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

要替换无效字符(并避免潜在的名称冲突像地狱* VS地狱$):

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

我同意Grauenwolf和会极力推荐的Path.GetInvalidFileNameChars()

下面是我的C#的贡献:

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

P.S。 - 这是更隐蔽比它应该是 - 我试图要简洁

下面是我的版本:

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

我不知道如何GetInvalidFileNameChars的结果进行计算,但“获取”表明,它是不平凡的,所以我缓存结果。此外,这仅横穿输入串一次,而不是多次,这样的遍历集合无效字符的上述的方案中,在一次更换它们的源串1英寸另外,我喜欢那里为主的解决方案,但我更愿意代替无效字符,而不是删除它们。最后,我的更换是一个字符,以避免在字符串中的字符转换为字符串作为我迭代。

我说所有的W / O做分析 - 这只是一个“感觉”对我很好。 :)

下面就是我现在使用(对于C#例如由于jcollum)功能:

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

我只是把这个在一个“助手”类为了方便。

如果你想快速去掉所有特殊字符,有时多个用户可读的文件名这个工作得很好:

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"
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);
    }
}

这就是我刚才添加到ClipFlair的( http://github.com/Zoomicon/ClipFlair )StringExtensions静态类(Utils.Silverlight项目)的基础上,从发布的杜尔高拱坝上面的链接到相关的计算器问题收集信息:

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)
}

为什么不将字符串转换为一个Base64当量这样的:

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

如果你想将其转换回,所以你可以阅读:

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

我用这与一个唯一的名称从随机描述保存PNG文件。

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;            
}

我觉得用这是快速和容易理解的:

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

此工作,因为一个stringIEnumerable作为char阵列并有一个string构造串,需要一个char阵列。

许多前面回答建议使用Path.GetInvalidFileNameChars()这似乎是一个坏的解决方案给我。我鼓励你使用白名单,而不是黑名单,因为黑客们总能找到办法,最终绕过它。

下面是代码可以使用的示例:

    string whitelist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.";
    foreach (char c in filename)
    {
        if (!whitelist.Contains(c))
        {
            filename = filename.Replace(c, '-');
        }
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top