首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Windows上验证文件名

在Windows上验证文件名
EN

Stack Overflow用户
提问于 2011-07-18 15:51:45
回答 7查看 31.9K关注 0票数 55
代码语言:javascript
运行
复制
public static boolean isValidName(String text)
{
    Pattern pattern = Pattern.compile("^[^/./\\:*?\"<>|]+$");
    Matcher matcher = pattern.matcher(text);
    boolean isMatch = matcher.matches();
    return isMatch;
}

此方法是否保证Windows上的文件名有效?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-07-24 11:26:14

考虑到前面的cited MSDN documentation中指定的要求,下面的正则表达式应该可以做得很好:

代码语言:javascript
运行
复制
public static boolean isValidName(String text)
{
    Pattern pattern = Pattern.compile(
        "# Match a valid Windows filename (unspecified file system).          \n" +
        "^                                # Anchor to start of string.        \n" +
        "(?!                              # Assert filename is not: CON, PRN, \n" +
        "  (?:                            # AUX, NUL, COM1, COM2, COM3, COM4, \n" +
        "    CON|PRN|AUX|NUL|             # COM5, COM6, COM7, COM8, COM9,     \n" +
        "    COM[1-9]|LPT[1-9]            # LPT1, LPT2, LPT3, LPT4, LPT5,     \n" +
        "  )                              # LPT6, LPT7, LPT8, and LPT9...     \n" +
        "  (?:\\.[^.]*)?                  # followed by optional extension    \n" +
        "  $                              # and end of string                 \n" +
        ")                                # End negative lookahead assertion. \n" +
        "[^<>:\"/\\\\|?*\\x00-\\x1F]*     # Zero or more valid filename chars.\n" +
        "[^<>:\"/\\\\|?*\\x00-\\x1F\\ .]  # Last char is not a space or dot.  \n" +
        "$                                # Anchor to end of string.            ", 
        Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.COMMENTS);
    Matcher matcher = pattern.matcher(text);
    boolean isMatch = matcher.matches();
    return isMatch;
}

请注意,此正则表达式不会对文件名的长度施加任何限制,但根据平台的不同,实际的文件名可能会被限制为260或32767个字符。

票数 91
EN

Stack Overflow用户

发布于 2011-07-18 17:11:24

好吧,我认为下面的方法可以保证一个有效的文件名:

代码语言:javascript
运行
复制
public static boolean isValidName(String text)
{
    try
    {
        File file = new File(text);
        file.createNewFile();
        if(file.exists()) file.delete();
        return true;
    }
    catch(Exception ex){}
    return false;
}

你认为如何?

票数 16
EN

Stack Overflow用户

发布于 2011-07-28 06:41:47

一般来说,保证Windows文件名有效的方法--即创建该名称的文件是合法的--是不可能实现的。

保证Windows文件名无效相对简单。其他一些正则表达式试图做到这一点。然而,最初的问题要求更强的断言:一个保证文件名在Windows上有效的方法。

在其他答案中引用的MSDN reference指示Windows文件名不能包含“目标文件系统不允许的任何其他字符”。例如,包含NUL的文件在某些文件系统上是无效的,扩展的Unicode字符在一些较旧的文件系统上也是无效的。因此,名为☃.txt的文件在某些情况下是有效的,但在其他情况下则无效。因此,假设的isValidName(\"☃\")是否会返回true取决于底层文件系统。

但是,假设这样的函数是保守的,并且要求文件名由可打印的ASCII字符组成。所有现代版本的视窗系统本身都支持NTFS、FAT32和FAT16文件格式,这些文件格式接受Unicode文件名。但是可以安装任意文件系统的驱动程序,并且可以自由创建不允许使用字母'n‘的文件系统。因此,即使是像"snowman.txt“这样的简单文件也不能”保证“有效。

但即使把极端的情况放在一边,还有其他的复杂情况。例如,名为"$LogFile“的文件不能存在于NTFS卷的根目录中,但可以存在于该卷的其他位置。因此,如果不知道目录,我们就无法知道"$LogFile“是否是一个有效的名称。但是,如果"c:\data\“是指向另一个NTFS卷根的符号链接,那么即使"C:\data\$LogFile”也可能是无效的。(同样,如果D:是NTFS卷的子目录的别名,则"D:\$LogFile“也是有效的。)

甚至还有更复杂的情况。例如,文件上的备用数据流在NTFS卷上是合法的,因此"snowman.txt:☃“可能是有效的。三种主要的Windows文件系统都有路径长度重组,因此文件名的有效性也是路径的函数。但是,如果路径是虚拟别名、映射的网络驱动器或符号链接,而不是卷上的物理路径,则物理路径的长度甚至可能对isValidName不可用。

其他一些人提出了一种替代方案:使用建议的名称创建一个文件,然后将其删除,当且仅当创建成功时才返回true。这种方法有几个实际和理论问题。如前所述,其一是有效性是文件名和路径的函数,因此c:\test\☃.txt的有效性可能不同于c:\test2\☃.txt的有效性。此外,由于许多与文件的有效性无关的原因,该函数将无法写入文件,例如没有对目录的写入权限。第三个缺陷是,文件名的有效性不一定是不确定的:例如,假设的文件系统可能不允许替换已删除的文件,或者(在理论上)甚至可以随机决定文件名是否有效。

另一种方法是,创建一个isInvalidFileName(String text)方法,如果保证文件在Windows中无效,则该方法返回true;文件名如"aux“、"*”和“abc.txt”。将返回true。文件创建操作将首先检查文件名是否被保证是无效的,如果返回false,则停止。否则,该方法可能会尝试创建文件,同时准备应对由于文件名无效而无法创建文件的边缘情况。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6730009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档