What character sequence should I not allow in a filename?
我在测试后发现linux允许文件名中除
建议我删除前导和尾随空格,我计划只是因为通常用户并不意味着有前导/尾随空格。
可能存在哪些有问题的序列以及我应该考虑不允许的序列?
我也在考虑为了方便而不允许在Windows中使用非法字符。 我想我可能不会在开头允许短划线(破折号是一个合法的窗口角色)
你的问题有点令人困惑,因为你详细谈论Linux,但是在对另一个答案的评论中,你说你正在为人们下载生成文件名,这可能意味着你对文件系统和操作系统完全没有任何控制权。文件将被存储,使Linux完全无关紧要。
出于这个答案的目的,我将假设你的问题是错误的,你的评论是正确的。
目前使用的绝大多数操作系统和文件系统大致分为三类:POSIX,Windows和MacOS。
POSIX规范非常清楚可以保证在所有POSIX系统中可移植的文件名是什么样的。您可以使用的字符在Open Group Base Specification的第3.276节(可移植文件名字符集)中定义为:
1 2 3 | ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789._- |
您可以依赖的最大文件名长度在第13.23.3.5节中定义(
因此,一个长达14个字符且仅包含上面列出的65个字符的文件名在所有符合POSIX标准的系统上都可以安全使用,它可以为您提供24407335764928225040435790组合(或大约84位)。
如果您不想惹恼用户,则应添加两个限制:不要使用短划线或点开始文件名。以点开头的文件名通常被解释为"隐藏"文件,除非明确请求,否则不会显示在目录列表中。并且以破折号开头的文件名可以被许多命令解释为选项。 (旁注:很多用户不知道
这使您处于23656340818315048885345458组合(仍为84位)。
Windows为此添加了一些新的限制:文件名不能以点结尾,文件名不区分大小写。这会将字符集从65个字符减少到39个字符(第一个字符为37个,最后一个字符为38个字符)。它没有添加任何长度限制,Windows可以处理14个字符就好了。
这将可能的组合减少到17866587696996781449603(73位)。
另一个限制是Windows将最后一个点之后的所有内容视为文件扩展名,表示文件的类型。如果你想避免潜在的混淆(比如,如果为文本文件生成像
您仍然有13090925539866773438463组合(73位)。
如果您不得不担心DOS,则适用其他限制:文件名由一个或两个部分组成(用点分隔),其中两个部分都不能包含点。第一部分的最大长度为8,3个字符中的第二个。同样,第二部分通常保留用于指示文件类型,只留下8个字符。
现在您有4347792138495个可能的文件名或41位。
好消息是您可以使用3个字符的扩展名来实际正确地指示文件类型,而不会破坏POSIX文件名限制(8 + 3 + 1 = 12 <14)。
如果您希望用户能够将文件刻录到使用ISO9660 Level 1格式化的CD-R上,那么您必须在任何地方禁用连字符,而不仅仅是第一个字符。现在,剩下的字符集看起来像
1 2 | ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789_ |
,它为您提供3512479453921组合(41位)。
我会决定什么是"有效"的操作系统和文件系统驱动程序。让用户输入他们想要的任何内容,然后传递给他们。以适当的方式处理来自操作系统的错误。例外情况是我认为剥离前导和尾随空格是合理的。如果人们想要创建带有嵌入空格或前导破折号或问号的文件名,并且他们选择的文件系统允许它,那么您应该尝试阻止它们。
可以在不同的安装点(或Windows中的驱动器)上安装不同的文件系统,这些文件系统对文件名中的合法字符有不同的规则。在你的应用程序中处理这类事情将比必要的工作更多,因为操作系统已经为你做了。
由于您似乎主要对Linux感兴趣,因此要避免的一件事是(典型的)shell将尝试解释的字符,例如,作为通配符。如果你坚持,你可以创建一个名为"*"的文件,但是你可能会有一些用户不喜欢它。
您是否正在开发一个应用程序,您必须要求用户自己创建文件?如果这就是您正在做的事情,那么您可以在应用程序中设置规则。 (例如,只允许[a-zA-Z0-9_。]并拒绝其余的特殊字符。)执行起来要简单得多。
我建议使用一组白名单字符。通常,文件名中的符号会使人烦恼。
通过各种方式允许人们使用a-z 0-9和unicode字符> 0x80,但不允许任意符号,例如&amp;而且,会造成很多烦恼,以及在不适当的地方举行。
我认为可以安全使用的ASCII符号是:fullstop下划线连字符
允许文件名中的任何其他ascii符号都会出现问题。
文件名也不应以ascii符号开头。文件名中的空格策略是棘手的,因为用户可能希望能够使用它们,但是一些文件名显然是愚蠢的(例如那些以空格开头的文件名)
urlencode所有字符串都用作文件名,你只需要担心长度。这个答案可能值得一读。