检查任意字符串是否为有效文件名的最简单方法


79

在我的应用程序中,用户可以输入文件名。在处理之前,我想检查输入的String在Windows Vista上是否为有效的文件名。

最简单的方法是什么?

有效,我是合法的,不存在的


当您说有效的文件名时,是指该文件存在的事实,还是在询问操​​作系统是否允许该名称?
Jesse McCulloch

4
是否有效(a)现有,(b)合法或(c)合法和不存在?
Anthony Pegram

对,我应该澄清一下。它应该是(C)leagl和不存在的
RoflcoptrException

4
@roflcopter:您必须在创建文件时简单地处理错误。由于文件系统是全局共享资源,因此涉及到存在性检查的任何文件系统操作在返回时都可能已经过时。
Ben Voigt

1
@Roflcoptr:在检查有效性和/或存在与实际尝试创建之间具有完全相同名称的文件不视为正常程序流程。您应该验证该文件不存在,但是当您实际创建文件时,该知识已经很旧了,应仅被视为有根据的猜测。它可能仍然是正确的,但不能保证
FredrikMörk2011年

Answers:


125

检查是否filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0!File.Exists(Path.Combine(someFolder, filename))


1
不过请检查Phil HUnt的答案;看来InvalidPathChars是一个过时的API,您应该改用GetInvalidFileNameChars()。
GendoIkari 2011年

3
<quote>不能保证从此方法返回的数组包含在文件名和目录名中无效的完整字符集。</ quote>此外,不建议使用该属性。
Ben Voigt

4
反例:"http://www.microsoft.com/"通过测试,但不是有效的文件名,同上"::::"
Ben Voigt

3
更多反例:“”无效,新的String('x',1024)也不有效。
Rasmus Faber

2
@shellster您可以通过告诉资源管理器将文件重命名为“ .txt”,在Windows资源管理器中将文件重命名为“ .txt”。只需提示(或“ .txt ........”也可以)。
罗伯特·麦基

37

反对GetInvalidFileNameChars()

var isValid = !string.IsNullOrEmpty(fileName) &&
              fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
              !File.Exists(Path.Combine(sourceFolder, fileName));

2
反例:"http://www.microsoft.com/"通过测试,但不是有效的文件名,同上"::::"
Ben Voigt

1
@Ben Voigt:您是正确的,::::被错误地认为是有效的。我已更正答案以指示< 0而不是== 0
菲尔·亨特

1
哦,我刚刚注意到您正在使用GetInvalidFileNameChars,而GetInvalidPathChars不像SLaks。只要仅测试文件名而不是路径文件名,就可以了。
Ben Voigt

@Ben Voigt:由于OP要求验证文件名,并且仅隐式地验证文件不存在,因此我使用了GetInvalidFileNameChars:-)
Phil Hunt,

11

如果要创建文件,则应使用文件对话框指定目录路径。有简短的文件名非法字符列表。

判断文件名是否可接受的唯一真正可靠的方法是尝试使用它。许可是一团糟。


文件对话框是一个红色的鲱鱼,但+1表示“只有真正可靠的方式……才可以尝试”。
Ben Voigt

1
同意 即使文件名不存在并且不包含非法字符,也有许多原因导致无法创建文件,最明显的原因是缺少目录的创建权限。
Bob Kaufman

在某些情况下,您需要保存到未知路径,但是您不希望用户选择确切的路径。在这些情况下,文件对话框不可行。
乔什·诺

2

我用这个:

public static bool IsValidFileName(string name) {
    if(string.IsNullOrWhiteSpace(name)) return false;
    if(name.Length > 1 && name[1] == ':') {
        if(name.Length < 4 || name.ToLower()[0] < 'a' || name.ToLower()[0] > 'z' || name[2] != '\\') return false;
        name = name.Substring(3);
    }
    if(name.StartsWith("\\\\")) name = name.Substring(1);
    if(name.EndsWith("\\") || !name.Trim().Equals(name) || name.Contains("\\\\") ||
        name.IndexOfAny(Path.GetInvalidFileNameChars().Where(x=>x!='\\').ToArray()) >= 0) return false;
    return true;
}

除保留名称,权限和长度限制外,应注意所有事项。这将接受相对和绝对文件名。


0

这只是一个想法。应该填充例外列表:

public static bool IsValidFilename(string filename)
{
    try
    {
        File.OpenRead(filename).Close();
    }
    catch (ArgumentException) { return false; }
    catch (Exception) { }
    return true;
}

如果文件不存在怎么办?
Mike Cheel

@MikeCheel该代码仅在抛出参数异常时返回false。仅在文件名无效的情况下抛出该异常。
Burak
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.