提问人:Jeff 提问时间:12/30/2009 最后编辑:Mateen UlhaqJeff 更新时间:10/15/2023 访问量:699940
Windows 和 Linux 目录名称中禁止使用哪些字符?
What characters are forbidden in Windows and Linux directory names?
问:
我知道这在 Linux 中是非法的,在 Windows 中也是非法的。/
*
"
/
\
<
>
:
|
?
我还错过了什么?我需要一个全面的指南,其中也考虑了双字节字符。
答:
禁止文件名字符的“综合指南”在 Windows 上不起作用,因为它保留了文件名和字符。是的,像 and 这样的字符是被禁止的,但有无数个名称仅由被禁止的有效字符组成。例如,空格和点是有效的文件名字符,但禁止仅由这些字符组成的名称。*
"
?
Windows 不区分大写字符和小写字符,因此如果已命名文件夹,则无法创建命名的文件夹。更糟糕的是,像 和 这样的看似允许的名称,以及许多其他名称,是保留的,不允许的。Windows 也有几个长度限制;如果移动到另一个文件夹,在一个文件夹中有效的文件名可能会失效。命名文件和文件夹的规则位于 Microsoft 文档中。A
a
PRN
CON
通常,不能使用用户生成的文本来创建 Windows 目录名称。如果要允许用户命名他们想要的任何内容,则必须创建安全名称(如 、 等),将用户生成的名称及其路径等效项存储在应用程序数据文件中,并在应用程序中执行路径映射。A
AB
A2
如果绝对必须允许用户生成的文件夹名称,则判断它们是否无效的唯一方法是捕获异常并假定名称无效。即使这样也充满了危险,因为为拒绝访问、脱机驱动器和驱动器空间不足而引发的异常与可能为无效名称引发的异常重叠。你正在打开一个巨大的伤害罐头。
评论
A.txt
a.TXT
COPY CON PRN
表示从键盘输入或可能的 stdin 读取,并将其复制到打印机设备。不确定它在现代窗户上是否仍然有效,但肯定是很长一段时间。在过去,您可以使用它来键入文本,并让点阵打印机简单地输出它。
好吧,如果只是出于研究目的,那么你最好的选择是看看这个关于文件名的维基百科条目。
如果你想编写一个可移植函数来验证用户输入并基于此创建文件名,简短的回答是不要。看看像 Perl 的 File::Spec 这样的可移植模块,以了解完成这样一个“简单”任务所需的所有跃点。
在Linux和其他Unix相关系统下,传统上只有两个字符不能出现在文件或目录的名称中,它们是NUL和斜杠。当然,斜杠可以出现在路径名中,分隔目录组件。'\0'
'/'
谣言1 说 Steven Bourne(以“贝壳”而闻名)有一个包含 254 个文件的目录,每个文件对应一个文件名中可能出现的单个字母(字符代码)(不包括 ,当然,该名称是当前目录)。它被用来测试 Bourne shell,并经常对备份程序等粗心的程序造成严重破坏。/
'\0'
.
其他人已经介绍了Windows文件名的规则,并提供了有关该主题的Microsoft和Wikipedia的链接。
请注意,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 Kernighan & Pike 在 ['The Practice of Programming'](https://www.cs.princeton.edu/~bwk/tpop.webpage/) 中,在第 6 章 Testing, §6.5 Stress Tests 中也说了同样的话:
当史蒂夫·伯恩(Steve Bourne)编写他的Unix shell(后来被称为Bourne shell)时,他创建了一个包含254个文件的目录,其中包含一个字符名称,每个字节值一个,除了和斜杠,这两个字符不能出现在Unix文件名中。他使用该目录进行模式匹配和标记化的各种测试。(当然,测试目录是由程序创建的。在那之后的几年里,该目录一直是文件树遍历程序的祸根;它考验了他们毁灭。
'\0'
请注意,该目录必须包含条目 . 和 .
.
,因此可以说是 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的维基百科。
评论
PATH
.
PATH
:
/
您可以使用白名单,而不是创建字符黑名单。考虑到所有因素,在文件或目录名称上下文中有意义的字符范围非常短,除非您有一些非常具体的命名要求,否则如果用户无法使用整个 ASCII 表,则他们不会将其与您的应用程序对立。
它不能解决目标文件系统中的保留名称问题,但使用白名单可以更容易地从源头上降低风险。
本着这种精神,这是一系列可以被认为是安全的角色:
- 字母 (a-z A-Z) - Unicode 字符(如果需要)
- 数字 (0-9)
- 下划线 (_)
- 连字符 (-)
- 空间
- 点 (.)
以及您希望允许的任何其他安全字符。除此之外,你只需要强制执行一些关于空格和点的额外规则。这通常就足够了:
- 名称必须至少包含一个字母或数字(以避免仅包含点/空格)
- 名称必须以字母或数字开头(以避免前导点/空格)
- 名称不能以点或空格结尾(如果存在,只需修剪它们,就像 Explorer 一样)
这已经允许相当复杂和荒谬的名称。例如,这些名称可以通过以下规则实现,并且在 Windows/Linux 中是有效的文件名:
A...........ext
B -.- .ext
从本质上讲,即使白名单字符如此之少,您仍然应该决定真正有意义的字符,并相应地验证/调整名称。在我的一个应用程序中,我使用了与上述相同的规则,但删除了任何重复的点和空格。
评论
禁止打印的 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)
不可打印的字符
如果您的数据来自允许不可打印字符的来源,则需要检查更多内容。
Linux/Unix:
0 (NULL byte)
窗户:
0-31 (ASCII control characters)
注意:虽然在 Linux/Unix 文件系统下创建文件名中带有控制字符的文件是合法的,但对于用户来说,处理此类文件可能是一场噩梦。
保留的文件名
保留以下文件名:
窗户:
CON, PRN, AUX, NUL COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9 LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9
(既可以单独使用,也可以使用任意文件扩展名,例如 )。
LPT1.txt
其他规则
窗户:
文件名不能以空格或点结尾。
macOS:
你没有要求它,但以防万一:根据上下文,冒号和正斜杠是不允许的(例如,Finder 支持斜杠,终端支持冒号)。(更多详情)
:
/
评论
*?<>"
NtQueryDirectoryFile
lpt1
lpt1.txt
cmd.exe
让 Windows 告诉您答案的简单方法是尝试通过资源管理器重命名文件,并在新名称中键入任何非法字符,例如反斜杠。Windows 将弹出一个消息框,告诉您非法字符列表:\
文件名不能包含以下任何字符:
\ / : * ?" < > |
以下是 Windows 10 专业版弹出窗口的屏幕截图:
请参阅:Microsoft 文档 - 命名文件、路径和命名空间 - 命名约定
评论
我有同样的需求,正在寻找推荐或标准参考,并遇到了这个线程。我目前在文件和目录名称中应避免使用的字符黑名单是:
$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" -> "@"
};
评论
@
b
lank spaces
(),-.;[]^_~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ.jpg
虽然唯一非法的 Unix 字符可能是 和 ,尽管应该包括一些命令行解释的考虑。/
NULL
例如,虽然在 Unix 中命名文件可能是合法的,但在命令行上使用此类文件名时可能会被误解。1>&2
2>&1
同样,也可以命名一个文件 ,但是当尝试从命令行访问它时,shell 将转换为其变量值。$PATH
$PATH
评论
$'myvalueis'
$ echo 'hi' > $'2>&1'
cat 2\>\&1
在Unix shell中,您几乎可以用单引号引用几乎每个字符。除了单引号本身,并且不能表示控制字符,因为没有展开。从带引号的字符串中访问单引号本身是可能的,因为您可以将字符串与单引号和双引号连接起来,例如可用于访问名为(此处也可以使用双引号)的文件。'
\
'I'"'"'m'
"I'm"
因此,您应该避免所有控制字符,因为它们太难在 shell 中输入。其余的仍然很有趣,尤其是以破折号开头的文件,因为大多数命令将它们读取为选项,除非您之前有两个破折号,或者您用 指定它们,这也隐藏了开始 .--
./
-
如果你想好听,不要使用 shell 和典型命令使用的任何字符作为语法元素,有时取决于位置,所以例如,你仍然可以使用 ,但不能作为第一个字符;与 相同,您只能在意思(“隐藏文件”)时将其用作第一个字符。当你是卑鄙的时,你的文件名是 VT100 转义序列 ;-),因此 ls 会使输出出现乱码。-
.
评论
截至 2017 年 4 月 18 日,在该主题的答案中,没有简单的字符和文件名的黑白列表 - 并且有很多回复。
我能想到的最好的建议是让用户按照他喜欢的方式命名文件。当应用程序尝试保存文件时使用错误处理程序,捕获任何异常,假设文件名是罪魁祸首(显然在确保保存路径也正常之后),并提示用户输入新文件名。为了获得最佳结果,请将此检查过程置于一个循环中,该循环一直持续到用户正确或放弃为止。最适合我(至少在 VBA 中)。
评论
在 Windows 中创建 Internet 快捷方式时,为了创建文件名,它会跳过非法字符,但正斜杠除外,正斜杠将转换为减号。
评论
对于 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
评论
" < > |
对路径和文件都无效)
在 Windows 10 (2019) 中,当您尝试键入以下字符时,错误会禁止它们:
文件名不能包含以下任何字符:
评论
下面是基于 Christopher Oezbek 的答案的 Windows c# 实现
containsFolder 布尔值使它变得更加复杂,但希望涵盖所有内容
/// <summary>
/// This will replace invalid chars with underscores, there are also some reserved words that it adds underscore to
/// </summary>
/// <remarks>
/// https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names
/// </remarks>
/// <param name="containsFolder">Pass in true if filename represents a folder\file (passing true will allow slash)</param>
public static string EscapeFilename_Windows(string filename, bool containsFolder = false)
{
StringBuilder builder = new StringBuilder(filename.Length + 12);
int index = 0;
// Allow colon if it's part of the drive letter
if (containsFolder)
{
Match match = Regex.Match(filename, @"^\s*[A-Z]:\\", RegexOptions.IgnoreCase);
if (match.Success)
{
builder.Append(match.Value);
index = match.Length;
}
}
// Character substitutions
for (int cntr = index; cntr < filename.Length; cntr++)
{
char c = filename[cntr];
switch (c)
{
case '\u0000':
case '\u0001':
case '\u0002':
case '\u0003':
case '\u0004':
case '\u0005':
case '\u0006':
case '\u0007':
case '\u0008':
case '\u0009':
case '\u000A':
case '\u000B':
case '\u000C':
case '\u000D':
case '\u000E':
case '\u000F':
case '\u0010':
case '\u0011':
case '\u0012':
case '\u0013':
case '\u0014':
case '\u0015':
case '\u0016':
case '\u0017':
case '\u0018':
case '\u0019':
case '\u001A':
case '\u001B':
case '\u001C':
case '\u001D':
case '\u001E':
case '\u001F':
case '<':
case '>':
case ':':
case '"':
case '/':
case '|':
case '?':
case '*':
builder.Append('_');
break;
case '\\':
builder.Append(containsFolder ? c : '_');
break;
default:
builder.Append(c);
break;
}
}
string built = builder.ToString();
if (built == "")
{
return "_";
}
if (built.EndsWith(" ") || built.EndsWith("."))
{
built = built.Substring(0, built.Length - 1) + "_";
}
// These are reserved names, in either the folder or file name, but they are fine if following a dot
// CON, PRN, AUX, NUL, COM0 .. COM9, LPT0 .. LPT9
builder = new StringBuilder(built.Length + 12);
index = 0;
foreach (Match match in Regex.Matches(built, @"(^|\\)\s*(?<bad>CON|PRN|AUX|NUL|COM\d|LPT\d)\s*(\.|\\|$)", RegexOptions.IgnoreCase))
{
Group group = match.Groups["bad"];
if (group.Index > index)
{
builder.Append(built.Substring(index, match.Index - index + 1));
}
builder.Append(group.Value);
builder.Append("_"); // putting an underscore after this keyword is enough to make it acceptable
index = group.Index + group.Length;
}
if (index == 0)
{
return built;
}
if (index < built.Length - 1)
{
builder.Append(built.Substring(index));
}
return builder.ToString();
}
评论
StringBuilder
filename
讨论不同的可能方法
定义方面的困难,什么是合法的,什么是不合法的,已经解决了,并提出了白名单。但不仅是 Windows,许多 Unixoid 操作系统都支持 8 位以上的字符,例如 Unicode。您还可以在这里讨论诸如 UTF-8 之类的编码。您可以考虑 Jonathan Leffler 的评论,他在评论中提供了有关现代 Linux 的信息并描述了 MacOS 的详细信息。维基百科指出,(例如),
修饰符字母冒号 [(见下文 7.) ]有时用于 Windows 文件名,因为它与用于文件名的 Segoe UI 字体中的冒号相同。不允许使用 [继承的 ASCII] 冒号本身。
因此,我想提出一种更自由的方法,使用 Unicode 同形字符来替换“非法”字符。我发现在我的类似用例中的结果更具可读性,并且它仅受所用字体的限制,该字体非常广泛,Windows 默认值为 3903 个字符。此外,您甚至可以从替换中恢复原始内容。
使用整个 Unicode 块(例如“fullwidth”)作为替换
为了保持井井有条,我总是会给角色、它的名字和十六进制数字表示。在评论中,i30817 谈到了仅为“滥用非法字符的愚蠢操作系统”保留范围的想法,这基本上是 Bill Sellers 显然所做的:“它不那么漂亮,但它总是有效,而且更容易记住。在候选块中,有全角、小格式变体、组合/修饰符/覆盖(见下文 4.)或半角字符。请考虑下表的概述:
角色名称 | 原始代码 | 原始字符 | 全角代码 | 全角字符 | 小型变体 | 小型变体代码 |
---|---|---|---|---|---|---|
1. 星号 | U+2A | * |
U+FF0A | * |
﹡ |
U+FE61型 |
2. 句号 | U+2E | . |
U+FF0E | . |
﹒ |
U+FE52型 |
3. 引号 | U+22型 | " |
U+FF02型 | " |
没有 | |
4. 反向固相线 | U+5C | \ |
U+FF3C | \ |
﹨ |
U+FE68型 |
5. 固相线 | U+2楼 | / |
U+FF0F | / |
没有 | |
6.1. 左方括号 | U+5B | [ |
U+FF3B | [ |
﹝ (仅限) |
U+FE5D |
6.2. 右方括号 | U+5D | ] |
U+FF3D | ] |
﹞ (仅限) |
U+FE5E |
7. 结肠 | U+3A型 | : |
U+FF3A | : |
﹕ |
U+FE55型 |
8. 分号 | U+3B型 | ; |
U+FF1B | ; |
﹔ |
U+FE54型 |
9. 垂直线 | U+7C | | |
U+FF5C | | |
没有 | |
10. 逗号 | U+2C | , |
U+FF0C | , |
﹐ |
U+FE50型 |
11. 问号 | U+3楼 | ? |
U+FF1F | ? |
﹖ |
U+FE56型 |
12.1. 大于符号 | U+3E | > |
U+FF1E | > |
﹥ |
U+FE65型 |
12.2. 小于符号 | U+3C | < |
U+FF1C | < |
﹤ |
U+FE64型 |
13. Circumflex 口音 | U+5E | ^ |
U+FF3E | ^ |
没有 |
一些全角字符(1、6.1、6.2 和 11)也包含在下面的“更多可能的选择和研究说明”中。
如何键入非标准字符
假设您要键入 .要获取其所有信息,您始终可以在合适的平台上搜索此字符 (),例如此 Unicode 查找或该 Unicode 表(仅允许搜索名称,在本例中为“Tifinagh Letter Yan”)。您应该获取其 Unicode 编号和 HTML 代码(请注意,2D4F
是 11599
的十六进制)。有了这些知识,您就有多种选择来生成这些特殊字符,包括使用ⵏ (Tifinagh Letter Yan)
ⵏ
U+2D4F
ⵏ
- 代码点到 Unicode 转换器或再次 Unicode 查找(请在搜索十六进制时添加)以将数字表示反向转换为 Unicode 字符(请记住将下面的代码点基数分别设置为十进制或十六进制)
0x
- Autohotkey 中的单行 makro:键入而不是字符串 - 这是我输入这些特殊字符的方式,如果有共同的兴趣,可以共享我的 Autohotkey 脚本
:?*:altpipe::{U+2D4F}
ⵏ
altpipe
- Alt字符或替代代码,按住 ,后跟所需字符的十进制数(更多信息,例如,此处,查看此处或那里的表格)。对于示例,这将是 +。请注意,许多程序并不完全支持所有 unicode 的 Windows 功能(截至撰写本文时)。Microsoft Office 是一个例外,它通常可以工作,其他一些操作系统提供类似的功能。在 MS Word 中输入这些带有 Alt 组合的字符也是 Wally Brockway 在他前面提到的答案中建议的方式¹⁴ - 如果您不想将所有十六进制值转换为它们的十进制 asc,您可以在那里找到其中的一些¹⁴。altAlt11599
- 在 MS Office 中,您还可以使用本 MS 文章中所述的 + 来生成字符ALTX
- 大多数操作系统都提供字符映射附件,您可以在其中找到特殊字符,通常它们还包括按名称搜索的选项
- 如果你很少需要它,你当然仍然可以复制粘贴你选择的特殊字符,而不是输入它
更多可能的选择和研究笔记
所以你对更广泛的角色的外观不满意吗?有很多选择。注意:十六进制数表示不区分大小写,前导零可以自由添加或省略,例如,并且是等效的。如果可用,我会尝试指出更多信息或替代方案 - 请随时向我展示更多或更好的信息。U+002A
u+2a
您可以使用列出的众多选项之一来代替 (),例如,或 . 将变音符号组合起来也可能是一个有效的选择。您可以阅读 4.有关组合字符的详细信息。*
U+2A * ASTERISK
U+2217 ∗ (ASTERISK OPERATOR)
Full Width Asterisk U+FF0A *
u+20f0 ⃰ combining asterisk above
而不是 (),其中一个可能是一个不错的选择,例如。.
U+2E . full stop
⋅ U+22C5 dot operator
代替 (),您可以使用 ,更多替代项请参阅此处。在这种情况下,我还包括 Wally Brockway 回答的一些好建议,并且 - 从现在开始,我将用 ¹⁴ 表示来自该来源的想法。"
U+22 " quotation mark
“ U+201C english leftdoublequotemark
u+2036 ‶ reversed double prime
u+2033 ″ double prime
您可以使用 (other here) 或 ¹⁴ 代替 (),而不是 ()。您也可以尝试 或 但请注意某些字符的间距,包括 or 字符。它们本身没有宽度,可以产生类似 --> ̸th̷is 的东西,即(为澄清这 6 个字符而添加下划线)。添加空格后,你会得到 --> ̸ th ̷ is,即(加上两个空格,为 8 个字符)。第二个 () 在 stackoverflow-font 中看起来很糟糕。/
U+2F / SOLIDUS
∕ DIVISION SLASH U+2215
u+2044 ⁄ fraction slash
̸ U+0338 COMBINING LONG SOLIDUS OVERLAY
̷ COMBINING SHORT SOLIDUS OVERLAY U+0337
combining
overlay
̸_th̷_is
̸ _th ̷ _is
COMBINING SHORT SOLIDUS OVERLAY
您可以使用 (more) 或 ¹⁴ 代替 (),而不是 ()。
\
U+5C Reverse solidus
⧵ U+29F5 Reverse solidus operator
u+20E5 ⃥ combining reverse solidus overlay
要替换 () 和 (),您可以使用例如 和 (从这里开始,更多可能性在这里)。[
U+5B [ Left square bracket
]U+005D ] Right square bracket
U+FF3B[ FULLWIDTH LEFT SQUARE BRACKET
U+FF3D ]FULLWIDTH RIGHT SQUARE BRACKET
您可以使用 或 代替 (),(请参阅冒号(字母),有时用于 Windows 文件名,因为它与用于文件名的 Segoe UI 字体中的冒号相同。冒号本身是不允许的......来源和更多替代品见这里)。另一种选择是:¹⁴。:
u+3a : colon
U+2236 ∶ RATIO (for mathematical usage)
U+A789 ꞉ MODIFIER LETTER COLON
u+1361 ፡ ethiopic wordspace
您可以使用 () 代替 (),而不是 ()。;
u+3b ; semicolon
U+037E ; GREEK QUESTION MARK
对于 (),有一些很好的替代品,例如:、、(维基百科中的最后一个)或 。此外,框绘图字符还包含各种其他选项。|
u+7c | vertical line
U+2223 ∣ DIVIDES
U+0964 । DEVANAGARI DANDA
U+01C0 ǀ LATIN LETTER DENTAL CLICK
U+2D4F ⵏ Tifinagh Letter Yan
例如,您可以使用 () 代替 ()。,
, U+002C COMMA
‚ U+201A SINGLE LOW-9 QUOTATION MARK
对于 (),这些是很好的候选者:或(从这里和这里)。还有两个来自 Dingbats Block(搜索“问题”)和 ¹⁴。?
U+003F ? QUESTION MARK
U+FF1F ? FULLWIDTH QUESTION MARK
U+FE56 ﹖ SMALL QUESTION MARK
u+203d ‽ interrobang
虽然我的机器似乎接受它不变,但为了完整起见,我仍然想包括 () 和 ()。这里最好的替换可能也来自报价块,例如 和 分别。tifinagh 块仅包含 ¹⁴ 来替换 .最后一个概念是 和 。
>
u+3e greater-than sign
<
u+3c less-than sign
u+203a › single right-pointing angle quotation mark
u+2039 ‹ single left-pointing angle quotation mark
ⵦ (u+2D66)
<
⋖ less-than with dot u+22D6
⋗ greater-than with dot u+22D7
如需更多想法,您还可以查看此块。你还想有更多想法吗?您可以尝试绘制您想要的角色并查看此处的建议。如果您发现有价值的东西,请发表评论。
评论
对于任何寻找正则表达式的人:
const BLACKLIST = /[<>:"\/\\|?*]/g;
.NET Framework 为无效的文件系统字符提供以下函数:System.IO
这些函数应返回相应的结果,具体取决于运行 .NET 运行时的平台。也就是说,这些函数的文档页面中的备注说:
从此方法返回的数组不保证包含 文件和目录中无效的完整字符集 名字。完整的无效字符集可能因文件系统而异。
评论
我一直认为 Windows 文件名中禁止的字符意味着所有外来字符也将被取缔。无法使用 ,尤其让我恼火。有一天,我发现几乎只有那些字符被禁止。可以使用其他 Unicode 字符。因此,确定了与我能找到的被禁止字符最接近的 Unicode 字符,并为它们制作了 MS Word 宏,如 +、+ 等。现在,我使用替换字符在 Word 中形成文件名,并将其复制到 Windows 文件名中。到目前为止,我还没有遇到任何问题。? / :Alt?Alt:
以下是替换字符 ( + 十进制 Unicode) :Alt
- ⃰ ⇔ 8432Alt
- ⁄ ⇔ 8260Alt
- ⃥ ⇔ 8421Alt
- ∣ ⇔ 8739Alt
- ⵦ ⇔ 11622Alt
- ⮚ ⇔ 11162Alt
- ‽ ⇔ 8253Alt
- ፡ ⇔ 4961Alt
- ‵‵ ⇔ 8246Alt
- “ ⇔ 8243Alt
作为测试,我使用所有这些字符形成了一个文件名,Windows 接受了它。
评论
这在 Python 中对我来说已经足够了:
def fix_filename(name, max_length=255):
"""
Replace invalid characters on Linux/Windows/MacOS with underscores.
List from https://stackoverflow.com/a/31976060/819417
Trailing spaces & periods are ignored on Windows.
>>> fix_filename(" COM1 ")
'_ COM1 _'
>>> fix_filename("COM10")
'COM10'
>>> fix_filename("COM1,")
'COM1,'
>>> fix_filename("COM1.txt")
'_.txt'
>>> all('_' == fix_filename(chr(i)) for i in list(range(32)))
True
"""
return re.sub(r'[/\\:|<>"?*\0-\x1f]|^(AUX|COM[1-9]|CON|LPT[1-9]|NUL|PRN)(?![^.])|^\s|[\s.]$', "_", name[:max_length], flags=re.IGNORECASE)
另请参阅此过时的列表,了解其他遗留内容,例如 FAT32。=
例如,OP的问题已经在这里和这里得到了充分的回答。在这里,我只是通过展示如何在 Linux 上修复它来扩展这些答案:
在 Linux 中,查找所有带有 Windows 中禁止的字符的文件和文件夹名称
如果您使用的是 Linux,并且只想查找所有带有 Windows 中禁止的字符的文件和文件夹名称,则可以运行以下命令:
# Find all files and folders with any of these Windows-illegal characters in
# their name: \ : * ? " < > |
find . -name '*[\\:\*?\"<\>|]*'
例如,这非常有用,因此您可以手动清理或“修复”在 Linux 上编写的 git 代码存储库,您现在需要在 Windows 上克隆和使用。如果您不首先在文件和文件夹名称中找到并清除并修复所有与 Windows 不兼容的字符,则存储库将无法在 Windows 上克隆,并且您会看到如下错误,例如:
$ git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world.git
Cloning into 'eRCaGuy_hello_world'...
remote: Enumerating objects: 4342, done.
remote: Counting objects: 100% (1184/1184), done.
remote: Compressing objects: 100% (366/366), done.
remote: Total 4342 (delta 819), reused 1149 (delta 799), pack-reused 3158Receiving objects: 100% (4342/4342), 6.50 Mi
Receiving objects: 100% (4342/4342), 7.02 MiB | 6.50 MiB/s, done.
Resolving deltas: 100% (2725/2725), done.
error: invalid path 'cpp/class_copy_constructor_and_assignment_operator/Link to Copy constructor vs assignment operat
or in C++ - GeeksforGeeks%%%%% [see `t2 = t1; -- calls assignment operator, same as "t2.operator=(t1);" `].desktop'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'
在上面,您可以看到导致失败的原因,因为我的文件名在 Windows 中路径无效,导致存储库无法在 Windows 上克隆,因为它包含双引号 () 字符。因此,我将在 Linux 上手动重命名该文件,删除字符,并将更改推送到我的 git 存储库,以便我可以在 Windows 上克隆它。error: invalid path
git clone
cpp/class_copy_constructor_and_assignment_operator/Link to Copy constructor vs assignment operat or in C++ - GeeksforGeeks%%%%% [see `t2 = t1; -- calls assignment operator, same as "t2.operator=(t1);" `].desktop
"
"
保留 Windows 文件路径 <= 259 个字符,文件夹路径 <= 248 个字符 ( 错误:git clone
Filename too long
)
即使您通过使用上述命令查找从文件夹和文件名中删除了禁止的字符,请记住,Windows 限制仍然存在,将文件的总路径长度限制为 <= 259 个字符,或文件夹的 <= 248 个字符。请参阅此处:NTFS(Windows XP 和 Windows Vista)中的最大文件名长度?find . -name '*[\\:\*?\"<\>|]*'
MAX_PATH
如果违反此路径限制,然后尝试在 Windows 上访问存储库,则会收到以下错误:git clone
Filename too long
$ git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world.git
Cloning into 'eRCaGuy_hello_world'...
remote: Enumerating objects: 4347, done.
remote: Counting objects: 100% (1189/1189), done.
remote: Compressing objects: 100% (370/370), done.
remote: Total 4347 (delta 823), reused 1152 (delta 800), pack-reused 3158
Receiving objects: 100% (4347/4347), 7.03 MiB | 5.82 MiB/s, done.
Resolving deltas: 100% (2729/2729), done.
error: unable to create file cpp/class_copy_constructor_and_assignment_operator/Link to Copy constructor vs assignmen
t operator in C++ - GeeksforGeeks%%%%% [see `t2 = t1; -- calls assignment operator, same as ''t2.operator=(t1);'' `]
.desktop: Filename too long
Updating files: 100% (596/596), done.
Filtering content: 100% (8/8), 2.30 MiB | 2.21 MiB/s, done.
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'
请注意这部分,因为我的文件名长得离谱:
error: unable to create file cpp/class_copy_constructor_and_assignment_operator/Link to Copy constructor vs assignment operator in C++ - GeeksforGeeks%%%%% [see `t2 = t1; -- calls assignment operator, same as ''t2.operator=(t1);'' `].desktop: Filename too long
缩短长文件名以减少路径长度,提交并推送更改,然后再次尝试克隆。
引用:
在 Windows 10 Pro 上,我尝试在文件夹名称中键入 a,但出现以下弹出窗口错误:
"
我使用 https://regex101.com/(参见:https://regex101.com/r/lI5Lg9/1)来构建和测试正则表达式,以了解要转义的字符,方法是查看右侧的“解释”部分:
[\\:\*?\"<\>|]
评论
^
在 FAT 上是被禁止的