Check whether a string is a valid filename with Qt

后端 未结 6 1509
一个人的身影
一个人的身影 2021-02-18 22:08

Is there a way with Qt 4.6 to check if a given QString is a valid filename (or directory name) on the current operating system ? I want to check for th

6条回答
  •  难免孤独
    2021-02-18 22:56

    Based on User7116's answer here:

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

    I quit being lazy - looking for elegant solutions, and just coded it. I got:

    bool isLegalFilePath(QString path)
    {
        // Anything following the raw filename prefix should be legal.
        if (path.left(4)=="\\\\?\\")
            return true;
    
        // Windows filenames are not case sensitive.
        path = path.toUpper();
    
        // Trim the drive letter off
        if (path[1]==':' && (path[0]>='A' && path[0]<='Z'))
            path = path.right(path.length()-2);
    
        QString illegal="<>:\"|?*";
    
        foreach (const QChar& c, path)
        {
            // Check for control characters
             if (c.toLatin1() > 0 && c.toLatin1() < 32)
                return false;
    
            // Check for illegal characters
            if (illegal.contains(c))
                return false;
        }
    
        // Check for device names in filenames
        static QStringList devices;
    
        if (!devices.count())
            devices << "CON" << "PRN" << "AUX" << "NUL" << "COM0" << "COM1" << "COM2"
                    << "COM3" << "COM4" << "COM5" << "COM6" << "COM7" << "COM8" << "COM9" << "LPT0"
                    << "LPT1" << "LPT2" << "LPT3" << "LPT4" << "LPT5" << "LPT6" << "LPT7" << "LPT8"
                    << "LPT9";
    
        const QFileInfo fi(path);
        const QString basename = fi.baseName();
    
        foreach (const QString& s, devices)
            if (basename == s)
                return false;
    
        // Check for trailing periods or spaces
        if (path.right(1)=="." || path.right(1)==" ")
            return false;
    
        // Check for pathnames that are too long (disregarding raw pathnames)
        if (path.length()>260)
            return false;
    
        // Exclude raw device names
        if (path.left(4)=="\\\\.\\")
            return false;
    
        // Since we are checking for a filename, it mustn't be a directory
        if (path.right(1)=="\\")
            return false;
    
        return true;
    }
    

    Features:

    • Probably faster than using regexes
    • Checks for illegal characters and excludes device names (note that '\' is not illegal, since it can be in path names)
    • Allows drive letters
    • Allows full path names
    • Allows network path names
    • Allows anything after \\?\ (raw file names)
    • Disallows anything starting with \\.\ (raw device names)
    • Disallows names ending in "\" (i.e. directory names)
    • Disallows names longer than 260 characters not starting with \\?\
    • Disallows trailing spaces and periods

    Note that it does not check the length of filenames starting with \\?\, since that is not a hard and fast rule. Also note, as pointed out here, names containing multiple backslashes and forward slashes are NOT rejected by the win32 API.

提交回复
热议问题