我知道/在Linux中是非法的,下面这些在Windows中是非法的 (我认为)*。" / \ []:;|,

我还遗漏了什么?

然而,我需要一份全面的指南,一份考虑到各种因素的指南 双字节字符。链接到外部资源对我来说很好。

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


当前回答

在Windows中创建internet快捷方式时,为了创建文件名,它会跳过非法字符,除了正斜杠被转换为减号。

其他回答

截至2017年4月18日,这个话题的答案中没有简单的字符和文件名的黑白列表,而且有很多回复。

我能想到的最好的建议是让用户随意命名文件。当应用程序试图保存文件时,使用错误处理程序,捕捉任何异常,假定是文件名造成的错误(显然在确保保存路径也正确之后),并提示用户输入新的文件名。为了获得最好的结果,将这个检查过程放在一个循环中,直到用户正确或放弃为止。对我来说是最好的工作(至少在VBA)。

The forbidden printable ASCII characters are: Linux/Unix: / (forward slash) Windows: < (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) Non-printable characters If your data comes from a source that would permit non-printable characters then there is more to check for. Linux/Unix: 0 (NULL byte) Windows: 0-31 (ASCII control characters) Note: While it is legal under Linux/Unix file systems to create files with control characters in the filename, it might be a nightmare for the users to deal with such files. Reserved file names The following filenames are reserved: Windows: CON, PRN, AUX, NUL COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9 LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 (both on their own and with arbitrary file extensions, e.g. LPT1.txt). Other rules Windows: Filenames cannot end in a space or dot. macOS: You didn't ask for it, but just in case: Colon : and forward slash / depending on context are not permitted (e.g. Finder supports slashes, terminal supports colons). (More details)

您可以使用白名单,而不是创建字符黑名单。考虑到所有因素,在文件或目录名称上下文中有意义的字符范围非常短,除非您有一些非常特定的命名要求,否则如果用户不能使用整个ASCII表,他们不会反对您的应用程序。

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

本着这种精神,这是一个可以被认为是安全的字符范围:

字母(a-z a-z) -如果需要,也可以使用Unicode字符 数字(0 - 9) 下划线(_) 连字符(-) 空间 点号(.)

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

名称必须包含至少一个字母或数字(以避免只有点/空格) 名称必须以字母或数字开头(以避免前导点/空格) 名称不能以点或空格结尾(如果存在,只需修剪它们,就像资源管理器一样)

这已经允许相当复杂和无意义的名称。例如,在这些规则下,这些名称是可能的,并且在Windows/Linux中是有效的文件名:

一个 ........... ext B -。- - - - - - ext

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

在Linux和其他与unix相关的系统下,传统上只有两个字符不能出现在文件或目录的名称中,那就是NUL '\0'和斜杠'/'。当然,斜杠可以出现在路径名中,分隔目录组件。

有传言说,史蒂文·伯恩(因“贝壳”而出名)有一个包含254个文件的目录,一个文件对应一个可以出现在文件名中的每个字母(字符代码)(不包括/,'\0';名字。当然是当前的目录)。它被用来测试伯恩外壳,并经常对备份程序等不小心的程序造成严重破坏。

其他人已经介绍了Windows文件名的规则,并提供了微软和维基百科的相关链接。

注意MacOS X有一个不区分大小写的文件系统。目前的版本似乎允许在文件名中使用冒号,尽管在历史上并不一定总是这样:

$ echo a:b > a:b
$ ls -l a:b
-rw-r--r--  1 jonathanleffler  staff  4 Nov 12 07:38 a:b
$

但是,至少在macOS Big Sur 11.7中,文件系统不允许文件名不是有效的UTF-8字符串。这意味着文件名不能由UTF-8中始终无效的字节组成(0xC0, 0xC1, 0xF5-0xFF),并且不能使用延续字节0x80..0xBF作为文件名中的唯一字节。给出的错误是92非法字节序列。

POSIX定义了一个可移植文件名字符集,包括:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 . _ -

坚持使用完全由这些字符组成的名称可以避免大部分问题,不过Windows仍然增加了一些复杂性。


1

It was Kernighan & Pike in ['The Practice of Programming'](http://www.cs.princeton.edu/~bwk/tpop.webpage/) who said as much in Chapter 6, Testing, §6.5 Stress Tests:

When Steve Bourne was writing his Unix shell (which came to be known as the Bourne shell), he made a directory of 254 files with one-character names, one for each byte value except '\0' and slash, the two characters that cannot appear in Unix file names. He used that directory for all manner of tests of pattern-matching and tokenization. (The test directory was of course created by a program.) For years afterwards, that directory was the bane of file-tree-walking programs; it tested them to destruction.

注意,该目录必须包含条目。和. .,所以它可以说是253个文件(和2个目录),或者255个名称条目,而不是254个文件。这并不影响轶事的有效性,也不影响它所描述的仔细测试。

TPOP之前在 http://plan9.bell-labs.com/cm/cs/tpop和 http://cm.bell-labs.com/cm/cs/tpop但现在(2021-11-12)都坏了。 参见维基百科上的TPOP。

好吧,如果只是为了研究目的,那么你最好的选择是看看维基百科上关于文件名的条目。

如果您想编写一个可移植的函数来验证用户输入并基于此创建文件名,简单的回答是不要。看一看像Perl的File::Spec这样的可移植模块,了解一下完成这样一个“简单”任务所需的所有跳转。