我不应该允许在文件名中使用什么字符序列?

在testing之后,我发现linux允许除了/和null( \0 )之外的文件名中的任何字符。 那么我应该在文件名中不允许使用哪个序列? 我听说一个领先的-可能会混淆一些命令行程序,这对我来说并不重要,但如果他们决定收集一堆文件并用一些GNU程序过滤它,可能会困扰其他人。

有人build议我删除前导和尾随空格,我打算只是因为通常用户不意味着有前/后空格。

什么样的问题序列可能会存在,我应该考虑什么序列不允许? 为了方便起见,我也考虑不允许在窗口中使用非法字符。 我想我可能不允许破折号(破折号是一个合法的窗口字符)

你的问题有点令人困惑,因为你长篇大论地谈论Linux,但是在另一个答案的评论中,你说你正在生成文件名以供下载,这大概意味着你完全不能控制文件系统和操作系统这些文件将被存储,使Linux完全不相关。

为了这个答案的目的,我会假设你的问题是错误的,你的意见是正确的。

目前使用的绝大多数操作系统和文件系统大致分为三类:POSIX,Windows和MacOS。

POSIX规范非常清楚在所有 POSIX系统中保证可移植的文件名。 您可以使用的字符在开放组基本规范的第3.276节(便携式文件名字符集)中定义如下:

  ABCDEFGHIJKLMNOPQRSTUVWXYZ
 ABCDEFGHIJKLMNOPQRSTUVWXYZ
 0123456789 ._- 

您可以依赖的最大文件名长度在第13.23.3.5节( <limits.h> Minimum Values)中定义为14 。 (相关的常量是_POSIX_NAME_MAX 。)

所以,一个长达14个字符的文件名,只包含上面列出的65个字符,在所有符合POSIX标准的系统上都可以使用,这样可以使用24407335764928225040435790组合(或大约84位)。

如果你不想惹恼你的用户,你应该添加两个限制:不要用短划线或点开始文件名。 以点开头的文件名通常被解释为“隐藏”文件,除非明确要求,否则不会显示在目录列表中。 并且以短划线开头的文件名可能被许多命令解释为一个选项。 (旁注:很多用户不了解rm ./-rfrm -- -rf技巧,真是太棒了。)

这留给你23656340818315048885345458组合(仍然是84位)。

Windows为此添加了一些新的限制:文件名不能以点结束,文件名不区分大小写。 这将字符集从65个减少到39个字符(第一个为37个,最后一个字符为38个)。 它不添加任何长度的限制,Windows可以处理14个字符就好了。

这将可能的组合减少到17866587696996781449603(73位)。

另一个限制是Windows将最后一个点之后的所有内容视为表示文件类型的文件扩展名。 如果您想避免潜在的混淆(例如,如果为文本文件生成像abc.mp3这样的文件名),则应该完全避免使用点。

您仍然有13090925539866773438463的组合(73位)。

如果你不得不担心DOS,那么附加的限制就是适用的:文件名由一个或两个部分组成(用一个点分开),这两个部分都不能包含一个点。 第一部分的最大长度是8,第二个是3个字符。 同样,第二部分通常保留以指示文件类型,只留下8个字符。

现在你有4347792138495可能的文件名或41位。

好消息是,您可以使用3个字符的扩展名来正确指示文件类型,而不会破坏POSIX文件名限制(8 + 3 + 1 = 12 <14)。

如果您希望用户能够将文件刻录到ISO9660级别1格式化的CD-R上,则必须禁止连字符,而不仅仅是第一个字符。 现在,剩下的字符集看起来像

  ABCDEFGHIJKLMNOPQRSTUVWXYZ
 0123456789_ 

这给你3512479453921组合(41位)。

我将决定什么是“有效”的操作系统和文件系统驱动程序。 让用户输入他们想要的任何东西,然后传递它。 以适当的方式处理来自操作系统的错误。 我认为除去前后空格是合理的。 如果人们想要创建带有嵌入空格或破折号或问号的文件名,而且他们选择的文件系统允许,则不应该由您来阻止它们。

可以在不同的挂载点(或Windows驱动器)上安装不同的文件系统,这些文件系统在文件名中具有不同的合法字符规则。 在你的应用程序中处理这种事情将比所需要的更多的工作,因为操作系统已经为你做。

由于您似乎主要对Linux感兴趣,因此需要避免的一件事就是(典型的)shell尝试解释的字符,例如作为通配符。 如果你坚持,你可以创建一个名为“*”的文件,但你可能有一些用户不太感激。

你正在开发一个应用程序,你必须要求用户自己创建文件? 如果这就是你正在做的,那么你可以在你的应用程序中设置规则。 (例如,只允许[a-zA-Z0-9_。]并拒绝其余的特殊字符),这实施起来要简单得多。

urlencode所有的字符串作为文件名使用,你只需要担心长度。 这个答案可能值得一读。

我建议使用一组白名单字符。 一般来说,文件名中的符号会让人烦恼。

通过一切手段,允许人们使用az 0-9和unicode字符> 0x80,但不允许任意的符号,像&和的东西,会引起很多的烦恼,以及在不适当的地方fullstops。

我认为可以安全使用的ASCII符号是:fullstop下划线连字符

允许任何其他ascii符号在文件名是要求麻烦。

一个文件名也不应该以ascii符号开头。 文件名空间的策略是棘手的,因为用户可能期望能够使用它们,但是一些文件名显然是愚蠢的(例如那些以空格开始的文件名)