代码之家  ›  专栏  ›  技术社区  ›  Jeff

Windows和Linux目录名中禁止哪些字符?

  •  264
  • Jeff  · 技术社区  · 16 年前

    我知道/在Linux中是非法的,以下在Windows中是非法的 (我认为) * . " / \ [ ] : ; | = ,

    我还缺什么?

    不过,我需要一个全面的指南,并考虑到 双字节字符。链接到外部资源对我来说很好。

    我需要首先在文件系统上使用一个可能 包含禁止使用的字符,因此我计划将这些字符替换为 下划线。然后我需要将这个目录及其内容写入一个zip文件 (使用Java),所以有关ZIP目录名称的任何附加建议 会很感激的。

    12 回复  |  直到 7 年前
        1
  •  181
  •   Dour High Arch    11 年前

    禁止使用的文件名字符的__综合指南__在Windows上不起作用,因为它保留文件名和字符。是的,像这样的人物 * " ? 还有一些是禁止使用的,但是有无限多的名称只由禁止使用的有效字符组成。例如,空格和圆点是有效的文件名字符,但禁止仅由这些字符组成的名称。

    Windows不区分大小写字符,因此无法创建名为 A 如果一个名字 a 已经存在。更糟的是,似乎允许的名字 PRN CON 以及许多其他的,都是保留的,不被允许。Windows也有一些长度限制;如果移动到另一个文件夹中,一个文件夹中有效的文件名可能会变得无效。规则 naming files and folders 在MSDN上。

    通常,不能使用用户生成的文本来创建Windows目录名。如果你想让用户说出他们想要的任何名字,你必须创建安全的名字,比如 , AB , A2 等,将用户生成的名称及其路径等价物存储在应用程序数据文件中,并在应用程序中执行路径映射。

    如果您绝对必须允许用户生成的文件夹名,那么判断它们是否无效的唯一方法是捕获异常并假定名称无效。即使这样也充满了危险,因为拒绝访问、脱机驱动器和驱动器空间不足引发的异常与无效名称引发的异常重叠。你在打开一个巨大的伤害罐。

        2
  •  336
  •   Søren Løvborg    7 年前

    让我们保持简单,首先回答问题。

    1. 被禁止的 可打印的ASCII字符 是:

      • Linux/UNIX:

        / (forward slash)
        
      • 窗户:

        < (less than)
        > (greater than)
        : (colon - sometimes works, but is actually NTFS Alternate Data Streams)
        " (double quote)
        / (forward slash)
        \ (backslash)
        | (vertical bar or pipe)
        ? (question mark)
        * (asterisk)
        
    2. 不可打印字符

      如果您的数据来自一个允许非打印字符的源,那么还有更多要检查的内容。

      • Linux/UNIX:

        0 (NULL byte)
        
      • 窗户:

        0-31 (ASCII control characters)
        

      注: 在Linux/Unix文件系统下,创建文件名中包含控制字符的文件是合法的, it might be a nightmare for the users to deal with such files .

    3. 保留的文件名

      保留以下文件名:

      • 窗户:

        CON, PRN, AUX, NUL 
        COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9
        LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
        

        (无论是单独使用还是使用任意文件扩展名,例如 LPT1.txt )

    4. 其他规则

      • 窗户:

        文件名不能以空格或点结尾。

        3
  •  54
  •   Jonathan Leffler    7 年前

    在Linux和其他与Unix相关的系统中,只有两个字符不能出现在文件或目录的名称中,它们是nul '\0' 斜线 '/' .当然,斜杠可以出现在路径名中,分隔目录组件。

    谣言 Steven Bourne(以“shell”闻名)是否有一个目录,其中包含254个文件,每个字母(字符代码)对应一个文件名(不包括 / , ‘0’ 名字 . 当然是当前的目录)。它被用来测试BourneShell,并经常破坏不小心的程序,如备份程序。

    其他人已经讨论过窗户规则。

    请注意,MacOS X具有不区分大小写的文件系统。


    是Kernighan和Pike加入的 The Practice of Programming 世卫组织在第6章,测试,第6.5节压力测试中说过:

    当Steve Bourne编写他的Unix shell(后来被称为Bourne shell)时,他创建了一个包含254个文件的目录,其中有一个字符名,每个字节值一个,除了 ‘0’ 和斜杠,这两个字符不能出现在Unix文件名中。他使用这个目录进行模式匹配和标记化技术的各种测试。(测试目录当然是由一个程序创建的)多年之后,这个目录是文件树漫游程序的祸根;它测试了它们的破坏性。

        4
  •  30
  •   AeonOfTime    7 年前

    您可以使用 白名单 . 综上所述,在文件或目录名上下文中有意义的字符范围非常短,除非您有一些非常具体的命名要求,否则如果您的用户不能使用整个ASCII表,他们就不会将其与您的应用程序对立起来。

    它并不能解决目标文件系统中保留名称的问题,但是使用白名单可以更容易地降低源文件系统的风险。

    本着这种精神,这是一系列可以被视为安全的字符:

    • 字母(A-Z A-Z) -如果需要,也可以使用Unicode字符
    • 数字(0~9)
    • 下划线(下)
    • Hyphen(-)
    • 空间
    • 点(?)

    以及您希望允许的任何其他安全字符。除此之外,你只需要执行一些 关于空格和点的附加规则 . 这通常就足够了:

    • 名称必须至少包含一个字母或数字(以避免只包含点/空格)
    • 名称必须以字母或数字开头(以避免前导点/空格)
    • 名称不能以点或空格结尾(如果存在,只需像Explorer那样修剪这些点或空格)

    这已经允许使用非常复杂和荒谬的名称。例如,这些名称可以使用这些规则,并且在Windows/Linux中是有效的文件名:

    • A...........ext
    • B -.- .ext

    本质上,即使白名单中的字符太少,您仍然应该决定什么是真正有意义的,并相应地验证/调整名称。在我的一个应用程序中,我使用了与上面相同的规则,但是去掉了所有重复的点和空格。

        5
  •  25
  •   Leonardo Herrera    16 年前

    好吧,如果只是为了研究的目的,那么你最好的选择就是看看 this Wikipedia entry on Filenames .

    如果要编写一个可移植函数来验证用户输入并基于该函数创建文件名,那么简短的答案是 不要 .看看像Perl这样的可移植模块 File::Spec 一瞥完成这样一个“简单”的任务所需要的所有跳跃。

        6
  •  23
  •   raimue    10 年前

    让Windows告诉您答案的简单方法是尝试通过资源管理器重命名文件,然后键入/作为新名称。Windows将弹出一个消息框,告诉您非法字符的列表。

    A filename cannot contain any of the following characters:
        \ / : * ? " < > | 
    

    https://support.microsoft.com/en-us/kb/177506

        7
  •  5
  •   Wojciech Sciesinski    8 年前

    对于Windows,可以使用PowerShell检查它

    $PathInvalidChars = [System.IO.Path]::GetInvalidPathChars() #36 chars
    

    要显示UTF-8代码,可以转换

    $enc = [system.Text.Encoding]::UTF8
    $PathInvalidChars | foreach { $enc.GetBytes($_) }
    
    $FileNameInvalidChars = [System.IO.Path]::GetInvalidFileNameChars() #41 chars
    
    $FileOnlyInvalidChars = @(':', '*', '?', '\', '/') #5 chars - as a difference
    
        8
  •  1
  •   David Spector    7 年前

    截至2017年4月18日,本主题的答案中没有明显的简单的黑名单或白名单字符和文件名,而且有许多答案。

    我能想到的最好的建议是让用户随意命名文件。当应用程序试图保存文件时,使用错误处理程序,捕获任何异常,假定文件名是错误的(显然在确保保存路径正确之后),并提示用户输入新的文件名。为了获得最佳结果,请将此检查过程放入一个循环中,该循环将一直持续,直到用户正确执行或放弃为止。为我工作得最好(至少在维也纳国际机场)。

        9
  •  0
  •   Matthias Ronge    9 年前

    在Windows中创建Internet快捷方式时,若要创建文件名,它将跳过非法字符,但正斜杠除外,正斜杠转换为减号。

        10
  •  -1
  •   CodeMouse92    10 年前

    尽管唯一非法的Unix字符可能是 / NULL 尽管应考虑命令行解释。

    例如,虽然命名文件可能是合法的 1>&2 2>&1 在UNIX中,当在命令行上使用时,这样的文件名可能会被误解。

    同样,也可以命名一个文件 $PATH ,但当尝试从命令行访问它时,shell将转换 $路径 它的变量值。

        11
  •  -1
  •   forthy42    9 年前

    在UNIX shell中,几乎可以用单引号引用每个字符 ' .除了单引号本身,您不能表示控制字符,因为 \ 未展开。可以从带引号的字符串中访问单引号本身,因为可以用单引号和双引号连接字符串,如 'I'"'"'m' 可用于访问名为 "I'm" (此处也可以使用双引号)。

    因此,您应该避免使用所有控制字符,因为它们太难在shell中输入。其余的仍然很有趣,尤其是以破折号开头的文件,因为大多数命令将这些作为选项读取,除非您有两个破折号。 -- 或者用 ./ ,这也隐藏了开始 - .

    如果你想表现得好一点,不要使用shell和典型命令中用作句法元素的任何字符,有时是位置相关的,因此你仍然可以使用 - ,但不作为第一个字符;同 . ,您只能在表示第一个字符时将其用作第一个字符(“隐藏文件”)。如果你是认真的,你的文件名是vt100转义序列;-),这样一个ls就可以存储输出。

        12
  •  -5
  •   Meng Lu    10 年前

    我也有同样的需求,正在寻找推荐或标准参考资料,并且遇到了这个问题。我当前应该在文件名和目录名中避免的字符黑名单是:

    $CharactersInvalidForFileName = {
        "pound" -> "#",
        "left angle bracket" -> "<",
        "dollar sign" -> "$",
        "plus sign" -> "+",
        "percent" -> "%",
        "right angle bracket" -> ">",
        "exclamation point" -> "!",
        "backtick" -> "`",
        "ampersand" -> "&",
        "asterisk" -> "*",
        "single quotes" -> "“",
        "pipe" -> "|",
        "left bracket" -> "{",
        "question mark" -> "?",
        "double quotes" -> "”",
        "equal sign" -> "=",
        "right bracket" -> "}",
        "forward slash" -> "/",
        "colon" -> ":",
        "back slash" -> "\\",
        "lank spaces" -> "b",
        "at sign" -> "@"
    };