基于有限自动机原理实现路径有效性检测
最近在项目开发过程中遇到一个问题,是关于Windows传统DOS路径有效性检测的,在面对不同的指示为路径的字符串时,将它们作为输入,引申出来的几个问题。
- 如何判断其是否符合目前各种操作系统的文件管理的路径规范?
- 在文件本身是否存在作为可选项时,如何判断一个路径是否为有效的路径?
- 如何实现跨平台的路径有效性检测?
标识为路径的字符串由一个个字符或字符串组成,所以我想到了以字符或字符串为单位,从头到尾遍历字符串,并对这些单位进行判断和识别,例如是否存在磁盘名?磁盘名是否符合规范?其中的路径分隔符对于运行时平台是否有效?基于种种判断规则来组合判断指示为路径的字符串是否为有效的路径。而这个判断过程我设计为了一个有限自动机1,它非常适合干这种工作。
工程目录
- PathTool
- Rule
- IFilePathRule.cs
- IFolderPathRule.cs
- WindowsFilePathRule.cs
- WindowsFolderPathRule.cs
- FilePathTool.cs
- FolderPathTool.cs
- PathTool.cs
- WindowsPathSharedData.cs
- Rule
这个工具包括了文件和文件夹的路径有效性检测,统一通过PathTool进行调用,Rule目录下用于存储实现具体的路径检测逻辑的脚本,例如WindowsFilePathRule和WindowsFolderPathRule。目前仅实现了Windows系统的路径检测,可以通过IFilePathRule和IFolderPathRule接口进行其它平台的扩展。WindowsPathSharedData用来存储工具类的共享数据,例如文件或文件夹名称的特殊字符集、驱动器名称的特殊字符集等等。
分析
关于有限自动机(也称“有限状态机”),做游戏开发的朋友不会陌生,当一个实体存在多个不同的状态,而状态之间需要满足指定的条件进行切换时,就往往会想到状态机,而我们这里的实体是一个指示为路径的字符串,不同于游戏状态机,我们这里采用的是基于字典实现的状态表,状态表中的每个元素称为状态单元,每个状态单元中包括一到多个状态键值对,状态键值对的Key记录状态(这里是待识别的字符串),而Value则记录下一个状态单元索引。输入的字符串默认从第一个状态单元开始,然后根据匹配的Key获取到对应的Value,再根据Value跳转到其它状态单元,不断重复这个过程,直到最终得到结果。
| 状态单元 / 键值对序号 |
状态单元1 索引0 |
状态单元2 索引1 |
状态单元3 索引2 |
状态单元4 索引3 |
| 0 | Key:“driveName:\” Value:2 |
Key:“driveName:\” Value:2 |
Key:“folderName\” Value:2 |
Key:“” Value:3 |
| 1 | Key:“.\” Value:2 |
无 | 无 | 无 |
| 2 | Key:“..\” Value:2 |
无 | 无 | 无 |
| 3 | Key:“\?\” Value:1 |
无 | 无 | 无 |
上述这个表就是Windows路径检测所用的文件路径检测表。例如输入路径"C:\AAA\B.txt",根据路径分隔符"\“分割字符串为"C:\”、“AAA\”、“B.txt”,从状态单元1开始,"C:\“触发识别键值对序号0的"driveName:\”,其Value为2,跳转到状态单元3,"AAA\“触发识别键值对序号0的"folderName\”,其Value为2,但由于此时索引已检测到倒数第二个字符串单位,所以跳出循环,而"B.txt"将在跳出循环后单独进行检测,检测其为"文件名.文件扩展名"的组成,所以"C:\AAA\B.txt"识别为有效的Windows文件路径。
该工具类支持Windows系统的绝对路径、相对路径、超长路径的有效性检测,正向和反向路径分隔符也都能检测。
浙公网安备 33010602011771号