Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 在每个操作系统的文件路径中是否有任何非法字符?_Windows_Unix_Character_Filepath - Fatal编程技术网

Windows 在每个操作系统的文件路径中是否有任何非法字符?

Windows 在每个操作系统的文件路径中是否有任何非法字符?,windows,unix,character,filepath,Windows,Unix,Character,Filepath,是否有任何字符保证不会出现在Windows或Unix/Linux/OS X上的任何文件路径中 我之所以需要它,是因为我想将几个文件路径合并成一个字符串,然后稍后再将它们分开。您可以使用换行符,或者如果愿意,可以使用CR(十进制代码13)或LF(十进制代码10)。这是否合适取决于您对向用户显示连接字符串的要求——使用这种方法,它将在单独的行上打印其部分——这可能是非常好的,也可能是非常坏的(或者您可能不在乎……) 如果需要在单行上打印连接的字符串,请编辑问题以指定此附加要求;然后我们就可以开始了。

是否有任何字符保证不会出现在Windows或Unix/Linux/OS X上的任何文件路径中


我之所以需要它,是因为我想将几个文件路径合并成一个字符串,然后稍后再将它们分开。

您可以使用换行符,或者如果愿意,可以使用CR(十进制代码13)或LF(十进制代码10)。这是否合适取决于您对向用户显示连接字符串的要求——使用这种方法,它将在单独的行上打印其部分——这可能是非常好的,也可能是非常坏的(或者您可能不在乎……)


如果需要在单行上打印连接的字符串,请编辑问题以指定此附加要求;然后我们就可以开始了。

哈里·约翰斯顿在评论中写道:

这类问题的通用解决方案是在连接文件路径之前对其进行编码。例如,如果处理单字节字符串,可以将其转换为十六进制字符串;所以“你好”变成了“68656C6F”。(显然这不是最有效的解决方案!)

这是绝对正确的。请不要试图对文件名和保留字符做任何“棘手”的事情,因为它最终会在一些奇怪的情况下崩溃,而您的继任者将花很长时间试图修复损坏

事实上,如果您试图实现可移植性,我强烈建议您不要尝试创建任何文件名,包括除
[a-z0-9.]
以外的任何字符。(考虑Windows和OS X上的通用文件系统都可以在不区分大小写的模式下运行,其中
FooBar.txt
FooBar.txt
是相同的标识符。)

实际使用的一种非常紧凑的编码方案是制作一个“白名单集”,如
[A-z0-9\]
,并将“白名单集”之外的任何字符
ch
编码为
printf(“\u2x”,ch)
。所以
hello.txt
变成
hello\u 2etxt
,而
hello\u world.txt
变成
hello\u 5fworld\u 2etxt

由于每个
都是转义的,因此可以使用double-
作为分隔符:在Unix上,编码字符串
hello\u 2etxt\uuu\u再见\uuuuu2e\u 2e
唯一地标识文件名列表
['hello.txt'、'bye'、'..]

,文件名中只允许有两个字符;斜杠和空(零)字节。不允许使用斜杠,因为它将路径的组件彼此分隔开;空值,因为它标记名称的结尾。因此,路径名中唯一不允许的字符是空字节。我不知道有哪种操作系统允许文件名中包含空字节;因此,通过reductio ad absurdam,在每个O/S上的文件路径中唯一非法的字符是空字节。大多数人在大多数情况下不在文件名中使用控制字符,但它们可以出现。@JonathanLeffler:Windows本机API不使用以null结尾的字符串,因此null至少可能是一个合法字符。我不确定NTFS驱动程序是否真的允许这样做。实际上,这可能并不重要。:-)@callum:这类问题的一般解决方案是在加入文件路径之前对其进行编码。例如,如果处理单字节字符串,可以将其转换为十六进制字符串;所以“你好”变成了“68656C6F”。(显然这不是最有效的解决方案!)@HarryJohnston:如果Windows上的文件名中允许使用NUL字节,那么(a)我很惊讶,(b)在Windows和类似Unix的系统上,没有任何字符保证不会出现在任何文件路径中。@JonathanLeffler:我刚刚尝试过这个方法,在NTFS卷上,尝试为文件命名并嵌入null被拒绝。我相信这是特定于文件系统的,所以理论上,在备用文件系统中可以允许嵌入null。(但是,似乎不太可能存在这样的文件系统,或者至少不在生产环境中!)恕我直言,虽然这个答案涵盖了常见情况,但Unix中的文件名中允许使用换行符。取决于文件名中没有换行符,最终将中断。这就是为什么许多GNU实用程序现在有一个选项,使用空字节作为文件列表的记录分隔符;它是唯一不能出现在路径名中的字符,因此它是绝对安全的。(请参见GNU
find
with
-print0
xargs
with
-0
sort
with
-z
等。)