如何在.NET Core中实现跨操作系统通用的文件名非法字符校验?
关于.NET Core跨平台文件名校验的解决方案
首先明确:.NET Core 目前没有内置的、不依赖运行操作系统的全平台统一文件名非法字符校验能力。原生提供的Path.GetInvalidFileNameChars方法设计初衷就是返回当前运行环境的非法字符列表,适配当前系统的文件系统规则,天然不支持跨平台场景的统一校验需求。
针对你提到的云端存储跨端下载的场景,你可以自行实现统一校验规则,实现成本很低,不需要依赖第三方库:
- 第一步:整理全平台通用非法字符黑名单,合并Windows、macOS、Linux三大桌面平台所有禁止出现在文件名中的字符,参考清单如下:
- 特殊符号:
<、>、:、"、/、\、|、?、* - ASCII控制字符:编码0~31、127的所有不可见字符
- 特殊符号:
- 第二步:补充额外通用规则,避免更多兼容问题:
- 禁止文件名以
.、空格开头或结尾 - 禁止使用Windows系统保留文件名:
CON、PRN、AUX、NUL、COM1`COM9`、`LPT1`LPT9(不区分大小写)
- 禁止文件名以
- 你可以直接将上述规则硬编码到校验逻辑中,比正则实现的可读性和维护性更高,以下是简单的实现示例:
using System; using System.IO; using System.Linq; public static class FileNameValidator { // 全平台通用非法字符集合 private static readonly char[] InvalidFileNameChars = new char[] { '<', '>', ':', '"', '/', '\\', '|', '?', '*' }; // Windows保留文件名 private static readonly string[] ReservedFileNames = new string[] { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" }; public static bool IsValidCrossPlatformFileName(string fileName) { if (string.IsNullOrWhiteSpace(fileName)) return false; // 校验非法字符 if (fileName.Any(c => InvalidFileNameChars.Contains(c) || char.IsControl(c))) return false; // 校验首尾字符 if (fileName.StartsWith('.') || fileName.StartsWith(' ') || fileName.EndsWith('.') || fileName.EndsWith(' ')) return false; // 校验保留文件名(不区分大小写,忽略扩展名) string nameWithoutExt = Path.GetFileNameWithoutExtension(fileName).Trim().ToUpperInvariant(); if (ReservedFileNames.Contains(nameWithoutExt)) return false; return true; } }
如果有特殊需求,你还可以基于上述逻辑扩展规则,比如限制文件名长度避免不同文件系统的长度限制问题。
内容的提问来源于stack exchange,提问作者Gaurav Mantri
相关产品推荐
相关产品推荐

