和 Linux 下连回车都可以用作文件名不同,Windows 对于文件名还是有不少限制的,譬如不能用问号、星号等,这样的规定虽然偶尔会带来不便,但至少也不能说是不合理,因为通过正常途径你没法创建一个文件名里包含问号或者星号的文件。然而,Windows 规定了空格不能出现在文件名的尾部,但却很奇葩地允许你创建文件名尾部有空格的文件或文件夹,于是世界就崩坏了。

当你创建了一个文件名尾部有空格的文件之后,灾难就开始了。Windows 在访问文件的时候会先移除尾部的空格。因此如果你创建了一个名叫“abc<空格>”的文件,当你双击这个文件的时候,Windows 就会去找“abc”(没有空格)。如果你当前目录下刚好有一个文件叫“abc”的话,Windows 会错误地打开那个文件;而如果你当前目录底下没有“abc”,那系统就会直接告诉你找不到文件。

你也许会说,既然文件名不合法,那我把它改成合法的不就行了么?很遗憾,事情不是那么简单。当你在资源管理器里选中“abc<空格>”,并且试图把它改名为“def”的时候,系统在执行改名操作之前会先移除文件名尾部的空格,因此它会认为你想把“abc”(没有空格)改名为“def”,然后告诉你找不到文件。而且,这个倒霉的奇葩文件也删不掉,因为当你想删除它的时候,系统同样会认为你要删的是“abc”(没有空格)。

也许你会认为这仅仅是资源管理器的 bug,或许通过命令行可以解决这个问题。于是你打开命令行,输入:

ren "abc " "def"

很遗憾,一样不行,移除文件名尾部的空格是在 API 层面做的,因此不但你通过命令行无法绕过这个问题,就算是你写个程序来给它改名,你会发现你一样搞不定。

那么,对于这个文件我们是不是就完全无能为力了呢?其实事情倒是没有那么悲观,通过命令行我们还是可以搞定这个倒霉的文件的,只是我们需要通过完整路径来指定这个文件,这里说的完整路径是以双斜杠开头的完整路径,而不是我们通常所说的盘符开头的“全路径”:

\\?\<盘符>:\<路径>\文件名

例如:

ren "\\?\C:\Users\Me\Documents\abc " "def"

改名之后,文件打开、删除、改名就都没有问题了。我们终于成功摆脱了这个倒霉的文件!

如果名字结尾有空格的不是文件,而是文件夹的话,情况会更加麻烦一些:ren 命令会告诉你“命令语法不正确”,无法对文件夹进行改名操作。滇狐目前的解决方案是,创建一个新的文件夹,然后到名字里有空格的文件夹里把所有内容移动到新的文件夹里,最后使用 rmdir "\?..." 语法把“坏”文件夹删掉就可以了。这里比较有意思的地方是,“坏”文件夹里的所有文件都可以通过资源管理器正常操作,仅仅是文件夹本身不可以。

对于这样一个能给普通用户带来非常大的困扰的问题,微软似乎并不打算想办法解决它。微软写了洋洋洒洒一篇文章告诉大家“我们就是这么设计的”,那我也不知道该如何吐槽了。