Golang检查字符串是否为有效路径

Golang检查字符串是否为有效路径,go,Go,Golang filepath模块()包含一些用于操作路径的函数,并且可以使用os.Stat检查文件是否存在。有没有办法检查一个字符串是否真的形成了一个有效的路径(不管该路径上是否有文件)?这个问题听起来很简单,但实际上不是。以下是我发现的两种可能的解决方案: 解决方案1-学术 这里的想法是根据规则检查给定的文件路径 问题 操作系统(UNIX/Windows) 文件系统 保留关键字 操作系统 第一个是最简单的。Go为特定于操作系统的文件名/分隔符提供了各种工具 包中的示例: 包中的另一个: 文件

Golang filepath模块()包含一些用于操作路径的函数,并且可以使用
os.Stat
检查文件是否存在。有没有办法检查一个字符串是否真的形成了一个有效的路径(不管该路径上是否有文件)?

这个问题听起来很简单,但实际上不是。以下是我发现的两种可能的解决方案:

解决方案1-学术 这里的想法是根据规则检查给定的文件路径

问题
  • 操作系统(UNIX/Windows)
  • 文件系统
  • 保留关键字
  • 操作系统

    第一个是最简单的。Go为特定于操作系统的文件名/分隔符提供了各种工具

    包中的示例:

    包中的另一个:

    文件系统

    文件系统有不同的限制。允许的最大长度或字符集可能会有所不同。不幸的是,您无法判断(至少据我所知)您的路径将穿越哪个文件系统

    保留关键字

    拥有给定操作系统所有保留关键字的黑名单

    实施 对于这个解决方案,我将构建一个/

    折衷是它不能保证文件路径100%有效

    解决方案2-经验 尝试创建该文件,然后立即将其删除

    func IsValid(fp string) bool {
      // Check if file already exists
      if _, err := os.Stat(fp); err == nil {
        return true
      }
    
      // Attempt to create it
      var d []byte
      if err := ioutil.WriteFile(fp, d, 0644); err == nil {
        os.Remove(fp) // And delete it
        return true
      }
    
      return false
    }
    
    此解决方案的主要好处是,它更直观、更准确。如果文件已经存在或可以在给定路径上创建,则表示该文件有效。但是,由于访问受限,此解决方案也可能使有效路径无效

    总结
    第一种解决方案不如第二种解决方案准确,尽管从纯粹的角度来看更为正确。您应该选择的解决方案取决于您的需要。你喜欢假阳性还是假阴性?第一种解决方案会给您带来误报,而第二种解决方案会给您带来误报。

    AFAIK,在Unix系统上,任何不包含null字符的都可以是有效路径。但不确定Windows。@Ainar-G。。。看起来Windows至少对驱动器号有限制。Windows对文件名也有限制;例如,您不能命名文件
    aux
    aux.ext
    ,其中
    ext
    是您喜欢的任何扩展名,因为
    aux
    是msdos中访问aux端口的保留关键字,或者类似的“有效路径”高度依赖于系统。大多数系统不允许使用
    字符。在Windows上,所有这些都是不允许的:
    ?*:\“
    。Unix的Ext3文件系统只允许
    /
    和空字符,但linux也处理NTFS和FAT文件系统(这对应用程序是透明的),因此我只允许所有系统上允许的路径名…我不允许空字符和所有这些:
    ?%*:\“
    // VolumeName returns leading volume name.
    // Given "C:\foo\bar" it returns "C:" on Windows.
    // Given "\\host\share\foo" it returns "\\host\share".
    // On other platforms it returns "".
    func VolumeName(path string) string {
        return path[:volumeNameLen(path)]
    }
    
    func IsValid(fp string) bool {
      // Check if file already exists
      if _, err := os.Stat(fp); err == nil {
        return true
      }
    
      // Attempt to create it
      var d []byte
      if err := ioutil.WriteFile(fp, d, 0644); err == nil {
        os.Remove(fp) // And delete it
        return true
      }
    
      return false
    }