当前位置: 首页 > news >正文

C#/.NET 如何确认一个路径是否是合法的文件路径

很多方法要求传入一个字符串作为文件名或者文件路径,不过方法在实际执行到使用文件名的时候才会真正使用到这个文件名;于是这这种时候才会因为各种各样的异常发现文件名或者文件路径是不合法的。

有没有方法能够提前验证文件名或者文件路径是否是合法的路径呢?


这是一个不幸的结论 —— 没有!

实际上由我们自己写代码判断一个字符串是否是一个合法的文件路径是非常困难的,因为:

  1. 不同操作系统的路径格式是不同的;
  2. 同一个操作系统有各种各样不同的路径用途。

但你可能会说,就算有各种不同,也是可以穷举出来的。那么来看看穷举这些不同的情况需要多少代码吧:

  • Path.Windows.cs
  • PathHelper.Windows.cs
  • PathInternal.Windows.cs

看完这些代码,你是不是可以考虑放弃做 100% 精确的提前验证了?放弃是正解。

那么接下来如何验证呢?

使用 new FileInfo(string fileName) 类型和 Path.GetFullPath(string path) 方法来判断,则会使用到以上的代码,不过副作用是在路径不合法的时候抛出异常。

抛出异常

然而作为 API,验证路径的合法性也是需要抛出异常的,所以大可以继续使用这样的方法,用方法内部抛出的异常来提醒开发者传入的路径不合法。

但有时候是作为与用户的交互来判断路径或者文件名是否合法的,那么这个时候使用异常就不太合适了。毕竟 C#/.NET 的异常机制不应该参与正常的逻辑流程。

那么可以使用 Path.GetInvalidFileNameChars()GetInvalidPathChars() 来判断字符串中是否包含不合法的文件名字符或者路径字符。

以下代码来自 .NET Core 的库源码 Path.Windows.cs:

public static char[] GetInvalidFileNameChars() => new char[]
{
    '\"', '<', '>', '|', '\0',
    (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
    (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
    (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
    (char)31, ':', '*', '?', '\\', '/'
};

public static char[] GetInvalidPathChars() => new char[]
{
    '|', '\0',
    (char)1, (char)2, (char)3, (char)4, (char)5, (char)6, (char)7, (char)8, (char)9, (char)10,
    (char)11, (char)12, (char)13, (char)14, (char)15, (char)16, (char)17, (char)18, (char)19, (char)20,
    (char)21, (char)22, (char)23, (char)24, (char)25, (char)26, (char)27, (char)28, (char)29, (char)30,
    (char)31
};

参考资料

  • .net - Determine via C# whether a string is a valid file path - Stack Overflow
  • c# - How do I check if a given string is a legal/valid file name under Windows? - Stack Overflow
  • c# - Windows filepath and filename validation - Code Review Stack Exchange
  • Path.Windows.cs
  • PathHelper.Windows.cs
  • PathInternal.Windows.cs

我的博客会首发于 https://walterlv.com/,而 CSDN 和博客园仅从其中摘选发布,而且一旦发布了就不再更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://blog.csdn.net/wpwalter),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • 不使用 U 盘等任何工具全新安装 Windows 操作系统
  • C# 永远不会返回的方法真的不会返回
  • CentOS 的终端中如何搜索文件
  • 如何在命令行中监听用户输入文本的改变?
  • 使用 Xamarin 开发 iOS 键盘扩展(含网络访问)
  • 使用 Xamarin 开发 iOS 应用中需要注意的若干个问题
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • 使用 Xamarin 在 iOS 真机上部署应用进行调试
  • 在 Snoop 中使用 PowerShell 脚本进行更高级的 UI 调试
  • WPF 支持的多线程 UI 并不是线程安全的
  • ReSharper 在 C 盘占用了太多空间了,本文告诉你如何安全地删除或转移这些文件
  • WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了
  • git 的合并原理(递归三路合并算法)
  • git 合并策略
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • [LeetCode] Wiggle Sort
  • Golang-长连接-状态推送
  • idea + plantuml 画流程图
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Less 日常用法
  • Linux编程学习笔记 | Linux多线程学习[2] - 线程的同步
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 前端临床手札——文件上传
  • 如何用Ubuntu和Xen来设置Kubernetes?
  • 小李飞刀:SQL题目刷起来!
  • Mac 上flink的安装与启动
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • #14vue3生成表单并跳转到外部地址的方式
  • (附源码)ssm码农论坛 毕业设计 231126
  • (附源码)计算机毕业设计高校学生选课系统
  • (十五)使用Nexus创建Maven私服
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)iOS字体
  • (轉)JSON.stringify 语法实例讲解
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .Net Core和.Net Standard直观理解
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET6实现破解Modbus poll点表配置文件
  • [ 数据结构 - C++]红黑树RBTree
  • [AIGC] Java 和 Kotlin 的区别
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [C puzzle book] types
  • [echarts] y轴不显示0
  • [Linux] day07——查看及过滤文本
  • [Luogu P3527BZOJ 2527][Poi2011]Meteors(整体二分+BIT)
  • [MySQL]SQL优化之索引的使用规则
  • [NOI2022] 众数 题解
  • [NOIP2011DAY1P1]铺地毯
  • [POJ2728] Desert King
  • [Python设计模式] 第27章 正则表达式——解释器模式
  • [Shell]Linux常用快捷键
  • [Tcpdump] 网络抓包工具使用教程
  • [USACO5.5]Hidden Password