为啥用'\0'替换文件名中的无效字符?

Posted

技术标签:

【中文标题】为啥用\'\\0\'替换文件名中的无效字符?【英文标题】:Why replace invalid chars in a file name with '\0'?为什么用'\0'替换文件名中的无效字符? 【发布时间】:2016-11-23 08:50:49 【问题描述】:

我在同事的一个项目中偶然发现了这一点:

foreach (var invalidChar in Path.GetInvalidFileNameChars())
    fileName = fileName.Replace(invalidChar, '\0');

一般的想法很明显,但我想知道他为什么选择用 null char 的文字而不是“常规”char 或空字符串替换无效字符。

我想这个选择是有充分理由的(写这篇文章的人是我们团队的前辈),我想知道这个原因是什么。

【问题讨论】:

我会说这甚至是完全错误的......我的第一个猜测是这是来自旧的 C 代码,其中字符串以空值结尾。 MSDN 声明 1 到 31 + 其他一些字符是无效的,其中不包括 \0,但我很确定 \0 会导致问题。 询问您的高级开发人员是否还在您的团队中 @ThorstenDittmar mkay... 你有什么建议? @Jehof:接下来的几周他正在休假,但客户抱怨一些事情,这就是为什么我必须首先阅读该项目。所以我很想问他,但这不是一个选择:/ @garglblarg 我会用空字符串或类似下划线的东西替换,这样你就可以实际看到某些东西被替换了。正如我在编辑的评论中所说,我很确定在文件名中包含 \0 要么一开始就不起作用,要么导致 \0 标记字符串结尾的软件出现问题。 【参考方案1】:

在一些聪明人看来,没有 empty char 这样的东西。还应避免混淆空格(“”)和空字符串(“”)。

【讨论】:

没错,但你可以用空的字符串替换,这至少可以工作:-)【参考方案2】:

这取决于您的代码运行所在的操作系统。但在 Windows 上,char \0(0 作为 int)在文件名的无效字符列表中。

LinqPad(在 Windows 10 上运行)

Path.GetInvalidFileNameChars().Contains('\0').Dump(); //true

我认为这段代码是从另一种语言移植到 .net。

如果文件名包含无效字符,最好抛出异常(如果用户指定了名称),而不是用任何内容替换它们。

如果您需要替换它们,您应该选择一个字符,例如_,以明确表示可能有某些东西被替换了。

【讨论】:

这应该在 Windows 服务器中运行,所以如果 '\0' 本身是一个无效的字符,那将是毫无意义的练习。我会确保在这方面咨询 msdn。【参考方案3】:

在评论了这个问题之后,我正在寻找证明 \0 实际上不允许用于文件名的证据。 I found it:

使用当前代码页中的任何字符作为名称,包括 Unicode 字符和扩展字符集 (128–255) 中的字符,但以下字符除外: * 以下保留字符:(大于)、:(冒号)、"(双引号)、/(正斜杠)、\(反斜杠)、|(竖线或竖线)、?(问号),*(星号) * 整数值零,有时也称为 ASCII NUL 字符。 * 整数表示在 1 到 31 范围内的字符,但允许使用这些字符的备用数据流除外。

【讨论】:

以上是关于为啥用'\0'替换文件名中的无效字符?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在我的文件数据之前得到这些无效字符?

为啥 sed 不替换 NULL 字符 \x0?

bat命令怎么替换里面的字符串?

用来自不同文件的字符串替换文件中的字符串

用nodejs替换文件中的字符串

怎么用C语言对文件操作用特定内容替换其中某些内容