How do I check if a given string is a legal/valid file name under Windows?

后端 未结 27 1348
-上瘾入骨i
-上瘾入骨i 2020-11-22 09:38

I want to include a batch file rename functionality in my application. A user can type a destination filename pattern and (after replacing some wildcards in the pattern) I n

相关标签:
27条回答
  • 2020-11-22 10:21

    Also CON, PRN, AUX, NUL, COM# and a few others are never legal filenames in any directory with any extension.

    0 讨论(0)
  • 2020-11-22 10:21

    many of these answers will not work if the filename is too long & running on a pre Windows 10 environment. Similarly, have a think about what you want to do with periods - allowing leading or trailing is technically valid, but can create problems if you do not want the file to be difficult to see or delete respectively.

    This is a validation attribute I created to check for a valid filename.

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

    and the tests

    [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 讨论(0)
  • 2020-11-22 10:21

    One liner for verifying illigal chars in the string:

    public static bool IsValidFilename(string testName) => !Regex.IsMatch(testName, "[" + Regex.Escape(new string(System.IO.Path.InvalidPathChars)) + "]");
    
    0 讨论(0)
  • 2020-11-22 10:25

    I use this to get rid of invalid characters in filenames without throwing exceptions:

    private static readonly Regex InvalidFileRegex = new Regex(
        string.Format("[{0}]", Regex.Escape(@"<>:""/\|?*")));
    
    public static string SanitizeFileName(string fileName)
    {
        return InvalidFileRegex.Replace(fileName, string.Empty);
    }
    
    0 讨论(0)
  • 2020-11-22 10:26

    To complement the other answers, here are a couple of additional edge cases that you might want to consider.

    • Excel can have problems if you save a workbook in a file whose name contains the '[' or ']' characters. See http://support.microsoft.com/kb/215205 for details.

    • Sharepoint has a whole additional set of restrictions. See http://support.microsoft.com/kb/905231 for details.

    0 讨论(0)
  • 2020-11-22 10:28

    One corner case to keep in mind, which surprised me when I first found out about it: Windows allows leading space characters in file names! For example, the following are all legal, and distinct, file names on Windows (minus the quotes):

    "file.txt"
    " file.txt"
    "  file.txt"
    

    One takeaway from this: Use caution when writing code that trims leading/trailing whitespace from a filename string.

    0 讨论(0)
提交回复
热议问题