我知道/在Linux中是非法的,以下在Windows中是非法的(我认为) *
.
"
/
\
[
]
:
;
|
=
,
我还缺少什么?
但是,我需要一个全面的指南,并且需要考虑双字节字符 . 链接到外部资源对我来说没问题 .
我需要首先使用可能包含禁用字符的名称在文件系统上创建一个目录,所以我打算用下划线替换这些字符 . 然后我需要将此目录及其内容写入zip文件(使用Java),因此有关zip目录名称的任何其他建议将不胜感激 .
12 回答
虽然唯一非法的Unix字符可能是
/
和NULL
,但是应该包括对命令行解释的一些考虑 .例如,虽然在Unix中命名文件
1>&2
或2>&1
可能是合法的,但在命令行上使用时,这样的文件名可能会被误解释 .类似地,也可以命名文件
$PATH
,但是当尝试从命令行访问它时,shell会将$PATH
转换为其变量值 .禁用文件名字符的“综合指南”在Windows上不起作用,因为它保留了文件名和字符 . 是的,像
*
"
?
等字符是被禁止的,但是有无数个名称仅由禁止使用的有效字符组成 . 例如,空格和点是有效的文件名字符,但禁止仅由这些字符组成的名称 .Windows不区分大写字符和小写字符,因此如果已存在名为
a
的文件夹,则无法创建名为A
的文件夹 . 更糟糕的是,看似允许的名称如PRN
和CON
以及许多其他名称都是保留的,不允许使用 . Windows也有几个长度限制;如果移动到另一个文件夹,在一个文件夹中有效的文件名可能会无效naming files and folders的规则在MSDN上 .通常,您不能使用用户生成的文本来创建Windows目录名称 . 如果要允许用户命名他们想要的任何内容,则必须创建安全名称,如
A
,AB
,A2
等,在应用程序数据文件中存储用户生成的名称及其路径等效项,并在应用程序中执行路径映射 .如果绝对必须允许用户生成的文件夹名称,则判断它们是否无效的唯一方法是捕获异常并假设名称无效 . 即使这样也充满了危险,因为拒绝访问,脱机驱动器和驱动器空间的异常与可能因无效名称而被抛出的异常重叠 . 你正在开辟一个巨大的伤害 .
在Unix shell中,几乎可以引用单引号
'
中的每个字符 . 除单引号本身外,您无法表达控制字符,因为\
未展开 . 可以从带引号的字符串中访问单引号本身,因为您可以使用单引号和双引号连接字符串,例如'I'"'"'m'
,可用于访问名为"I'm"
的文件(此处也可以双引号) .因此,您应该避免使用所有控制字符,因为它们很难进入shell . 其余的仍然很有趣,特别是以破折号开头的文件,因为大多数命令都将这些作为选项读取,除非您之前有两个破折号
--
,或者您使用./
指定它们,这也隐藏了起始-
.如果你想做得好,不要使用shell和典型命令使用的任何字符作为语法元素,有时候依赖于位置,例如你仍然可以使用
-
,但不是第一个字符;与.
相同,只有在您指的时候才能将它用作第一个字符("hidden file") . 当你的意思是,你的文件名是VT100转义序列;-),所以ls使输出变得麻烦 .让我们保持简单并首先回答问题 .
禁止的 printable ASCII characters 是:
Linux / Unix:
如果您的数据来自允许不可打印字符的来源,则需要检查更多内容 .
注意:虽然在Linux / Unix文件系统下使用文件名中的控制字符创建文件是合法的,it might be a nightmare for the users to deal with such files .
以下文件名是保留的:
(均为自己和任意文件扩展名,例如
LPT1.txt
) .Other rules
Windows:
文件名不能以空格或点结尾 .
在Linux和其他与Unix相关的系统中,只有两个字符不能出现在文件或目录的名称中,它们是NUL
'\0'
和斜杠'/'
. 当然,斜杠可以出现在路径名中,将目录组件分开 .Rumour1认为Steven Bourne('shell'成名)有一个包含254个文件的目录,每个单个字母(字符代码)一个可以出现在文件名中(不包括
/
,'\0'
;名称.
当然是当前目录,当然) . 它被用来测试Bourne shell,并经常对诸如备份程序之类的粗心计划造成严重破坏 .其他人已经涵盖了Windows规则 .
请注意,MacOS X具有不区分大小写的文件系统 .
1在The Practice of Programming中的Kernighan&Pike在第6章测试,§6.5压力测试中说了很多:
您可以使用 whitelist ,而不是创建字符黑名单 . 考虑到所有因素,在文件或目录名称上下文中有意义的字符范围很短,除非您有一些非常具体的命名要求,否则如果用户不能使用整个ASCII表,则用户不会将其保留在应用程序中 .
它不能解决目标文件系统中保留名称的问题,但使用白名单可以更轻松地降低源上的风险 .
本着这种精神,这是一系列可以被认为是安全的角色:
字母(a-z A-Z) - 如果需要,也可以使用Unicode字符
数字(0-9)
下划线(_)
连字符( - )
空间
点( . )
以及您希望允许的任何其他安全字符 . 除此之外,你只需执行一些 additional rules regarding spaces and dots . 这通常就足够了:
名称必须至少包含一个字母或数字(以避免仅使用点/空格)
名称必须以字母或数字开头(以避免引导点/空格)
这已经允许非常复杂和荒谬的名称 . 例如,这些名称可以使用这些名称,并且是Windows / Linux中的有效文件名:
A...........ext
B -.- .ext
从本质上讲,即使白名单字符很少,您仍然应该确定实际有意义的内容,并相应地验证/调整名称 . 在我的一个应用程序中,我使用了与上面相同的规则,但剥离了任何重复的点和空格 .
好吧,如果仅用于研究目的,那么最好的办法是查看this Wikipedia entry on Filenames .
如果你想编写一个可移植的函数来验证用户输入并根据它创建文件名,那么简短的答案就是 don't . 看看像Perl的File::Spec这样的便携式模块,可以看到完成这样一个"simple"任务所需的所有跳跃 .
让Windows告诉您答案的简单方法是尝试通过资源管理器重命名文件并输入/为新名称 . Windows将弹出一个消息框,告诉您非法字符列表 .
https://support.microsoft.com/en-us/kb/177506
对于Windows,您可以使用PowerShell进行检查
要显示UTF-8代码,您可以转换
截至2017年4月18日,在本主题的答案中没有明显的黑色或白色字符和文件名列表 - 并且有很多回复 .
我能提出的最好的建议是让用户为他喜欢的文件命名 . 当应用程序尝试保存文件时使用错误处理程序,捕获任何异常,假设文件名是责备(显然确保保存路径也正常),并提示用户输入新文件名 . 为了获得最佳效果,请将此检查过程置于循环中,直到用户正确或放弃为止 . 对我来说最好(至少在VBA) .
在Windows中创建Internet快捷方式时,要创建文件名,它会跳过非法字符,但正斜杠除外,它会转换为减号 .
我有同样的需求,正在寻找推荐或标准参考,并遇到了这个线程 . 我目前在文件名和目录名中应避免使用的黑名单是: