Как проверить, является ли данная строка допустимым / допустимым именем файла в Windows? - PullRequest
154 голосов
/ 15 сентября 2008

Я хочу включить функцию переименования пакетного файла в моем приложении. Пользователь может ввести шаблон имени файла назначения и (после замены некоторых шаблонов в шаблоне) мне нужно проверить, будет ли это допустимое имя файла в Windows. Я пытался использовать регулярное выражение, например [a-zA-Z0-9_]+, но оно не включает много национальных символов из разных языков (например, умляуты и т. Д.) Каков наилучший способ сделать такую ​​проверку?

Ответы [ 26 ]

1 голос
/ 14 марта 2017

многие из этих ответов не будут работать, если имя файла слишком длинное и работает в среде, предшествующей Windows 10. Точно так же подумайте о том, что вы хотите делать с периодами - разрешение начального или конечного значения технически допустимо, но может создать проблемы, если вы не хотите, чтобы файл было трудно увидеть или удалить соответственно.

Это атрибут проверки, который я создал для проверки правильности имени файла.

public class ValidFileNameAttribute : ValidationAttribute
{
    public ValidFileNameAttribute()
    {
        RequireExtension = true;
        ErrorMessage = "{0} is an Invalid Filename";
        MaxLength = 255; //superseeded in modern windows environments
    }
    public override bool IsValid(object value)
    {
        //http://stackoverflow.com/questions/422090/in-c-sharp-check-that-filename-is-possibly-valid-not-that-it-exists
        var fileName = (string)value;
        if (string.IsNullOrEmpty(fileName)) { return true;  }
        if (fileName.IndexOfAny(Path.GetInvalidFileNameChars()) > -1 ||
            (!AllowHidden && fileName[0] == '.') ||
            fileName[fileName.Length - 1]== '.' ||
            fileName.Length > MaxLength)
        {
            return false;
        }
        string extension = Path.GetExtension(fileName);
        return (!RequireExtension || extension != string.Empty)
            && (ExtensionList==null || ExtensionList.Contains(extension));
    }
    private const string _sepChar = ",";
    private IEnumerable<string> ExtensionList { get; set; }
    public bool AllowHidden { get; set; }
    public bool RequireExtension { get; set; }
    public int MaxLength { get; set; }
    public string AllowedExtensions {
        get { return string.Join(_sepChar, ExtensionList); } 
        set {
            if (string.IsNullOrEmpty(value))
            { ExtensionList = null; }
            else {
                ExtensionList = value.Split(new char[] { _sepChar[0] })
                    .Select(s => s[0] == '.' ? s : ('.' + s))
                    .ToList();
            }
    } }

    public override bool RequiresValidationContext => false;
}

и тесты

[TestMethod]
public void TestFilenameAttribute()
{
    var rxa = new ValidFileNameAttribute();
    Assert.IsFalse(rxa.IsValid("pptx."));
    Assert.IsFalse(rxa.IsValid("pp.tx."));
    Assert.IsFalse(rxa.IsValid("."));
    Assert.IsFalse(rxa.IsValid(".pp.tx"));
    Assert.IsFalse(rxa.IsValid(".pptx"));
    Assert.IsFalse(rxa.IsValid("pptx"));
    Assert.IsFalse(rxa.IsValid("a/abc.pptx"));
    Assert.IsFalse(rxa.IsValid("a\\abc.pptx"));
    Assert.IsFalse(rxa.IsValid("c:abc.pptx"));
    Assert.IsFalse(rxa.IsValid("c<abc.pptx"));
    Assert.IsTrue(rxa.IsValid("abc.pptx"));
    rxa = new ValidFileNameAttribute { AllowedExtensions = ".pptx" };
    Assert.IsFalse(rxa.IsValid("abc.docx"));
    Assert.IsTrue(rxa.IsValid("abc.pptx"));
}
0 голосов
/ 02 декабря 2018

Один лайнер для проверки нелегальных символов в строке:

public static bool IsValidFilename(string testName) => !Regex.IsMatch(testName, "[" + Regex.Escape(new string(System.IO.Path.InvalidPathChars)) + "]");
0 голосов
/ 15 марта 2018

Этот чек

static bool IsValidFileName(string name)
{
    return
        !string.IsNullOrWhiteSpace(name) &&
        name.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
        !Path.GetFullPath(name).StartsWith(@"\\.\");
}

отфильтровывает имена с недопустимыми символами (<>:"/\|?* и ASCII 0-31), а также зарезервированные устройства DOS (CON, NUL, COMx). Он допускает начальные пробелы и имена из всех точек, соответствующие Path.GetFullPath. (Создание файла с начальными пробелами успешно выполняется в моей системе).


Используется .NET Framework 4.7.1, протестировано на Windows 7.

0 голосов
/ 02 октября 2017

Я получил эту идею от кого-то. - не знаю кто. Пусть ОС сделает тяжелую работу.

public bool IsPathFileNameGood(string fname)
{
    bool rc = Constants.Fail;
    try
    {
        this._stream = new StreamWriter(fname, true);
        rc = Constants.Pass;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Problem opening file");
        rc = Constants.Fail;
    }
    return rc;
}
0 голосов
/ 15 сентября 2008

Имена файлов Windows довольно неограничены, поэтому на самом деле это может даже не быть , что большая часть проблемы. Символы, которые запрещены Windows:

\ / : * ? " < > |

Вы можете легко написать выражение, чтобы проверить, присутствуют ли эти символы. Тем не менее, лучшим решением было бы попытаться назвать файлы так, как хочет пользователь, и предупредить их, когда имя файла не совпадает.

0 голосов
/ 10 января 2017

Я предлагаю просто использовать Path.GetFullPath ()

string tagetFileFullNameToBeChecked;
try
{
  Path.GetFullPath(tagetFileFullNameToBeChecked)
}
catch(AugumentException ex)
{
  // invalid chars found
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...