简体   繁体   English

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

[英]Easiest way to check if an arbitrary String is a valid filename

In my application the user can enter a filename.在我的应用程序中,用户可以输入文件名。 Before processing I'd like to check if the input String is a valid filename on Windows Vista.在处理之前,我想检查输入字符串是否是 Windows Vista 上的有效文件名。

Whats the easiest way to do that?最简单的方法是什么?

By valid I'm reffering to legal and non-existing通过有效,我指的是合法的和不存在的

检查filename.IndexOfAny(Path.GetInvalidFileNameChars()) < 0!File.Exists(Path.Combine(someFolder, filename))

Check against GetInvalidFileNameChars() :检查GetInvalidFileNameChars()

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

If the file is going to be created, You should use a file dialog to specify the directory path.如果要创建文件,您应该使用文件对话框来指定目录路径。 There's a short list of illegal characters for file names.文件名有一个非法字符的简短列表。

The only truly reliable way to tell if a file name is acceptable is to try it.判断文件名是否可接受的唯一真正可靠的方法是尝试它。 Permissions is a morass.权限是一个泥潭。

I use this:我用这个:

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

Should take care of everything but reserved names, permissions, and length restrictions.应该处理除保留名称、权限和长度限制之外的所有事情。 This accepts both relative and absolute filenames.这接受相对和绝对文件名。

This is just an idea.这只是一个想法。 One should populate the exception list:应该填写例外列表:

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

For first part(Valid Filename), I use all ways and a temporary file creation to check if a file can be named as expected or throws an exception.对于第一部分(有效文件名),我使用所有方法和临时文件创建来检查文件是否可以按预期命名或引发异常。
In some cases creating a file will not raise an exception until trying to delete it(eg: CON ).在某些情况下,创建文件不会引发异常,直到尝试删除它(例如: CON )。
I also usa removePath arg to dictate it that file is just the name of file without its path.我还removePath arg 来指示文件只是没有路径的文件名。

using System.IO;
using System.Text;
private static readonly byte[] TestFileBytes = Encoding.ASCII.GetBytes(@"X");
public bool IsFileNameValid(string file, bool removePath = false)
{
    try
    {
        if (string.IsNullOrEmpty(file))
            return false;

        string fileNamePart = removePath ? Path.GetFileName(file) : file;
        if (fileNamePart.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
            return false;

        string fileName = Path.Combine(Path.GetTempPath(), fileNamePart);
        using FileStream fileStream = File.Create(fileName);
        {
            fileStream.Write(TestFileBytes, 0, TestFileBytes.Length);
        }

        File.Delete(fileName);
        return true;
    }
    catch
    {
        return false;
    }
}

If there is any denial of access to temp folder use a custom folder for creating test file.如果拒绝访问临时文件夹,请使用自定义文件夹来创建测试文件。

This method will result false for .此方法将导致false . or .. or ... r any sequence of dot-only names in Windows, and also you can't create them manually, but those are not actually invalid names! or .. or ... r Windows 中的任何仅点名称序列,您也不能手动创建它们,但这些实际上不是无效名称! those are uncreatable names for file or something like that ;).这些是无法创建的文件名称或类似名称;)。

And for next part(Not exists) just use: !File.Exists(yourFileNameWithPath) .对于下一部分(不存在),只需使用: !File.Exists(yourFileNameWithPath)

If you create a DirectoryInfo for the file, it will throw an exception if there are any problems with the file/directory name, either invalid chars or length.如果为文件创建 DirectoryInfo,如果文件/目录名称有任何问题(无效字符或长度),它将引发异常。

DirectoryInfo di = new DirectoryInfo(myFileName);
Console.WriteLine("This filename/path could be valid. The folder might not exist yet though.")
if(di.Exists)
    Console.WriteLine("This file already exist.")

Not great that it is using exceptions for flow control, but you can be confident that it is right.它使用异常进行流控制并不是很好,但您可以确信它是正确的。 OTOH, if you already planned to give the calling code an exception, mission accomplished. OTOH,如果您已经计划给调用代码一个异常,那么任务就完成了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM