// 如果数据库目录不存在,则新建一个
if _, err := os.Stat(dirPath); os.IsNotExist(err) {   if err := os.MkdirAll(dirPath, os.ModePerm); err != nil {     return nil, err
  }
}

在阅览别人代码时对上述第一个语句产生疑问,因为os.Stat返回的是一个FileInfo用于描述文件,若err == nil 不就说明文件存在吗,为什么还需要os.IxNotExist(err)再进行一次判断。

后来发现,err != nil 并不能说明文件不存在...

查看os.IsNotExist源码可知

// IsNotExist returns a boolean indicating whether the error is known to
// report that a file or directory does not exist. It is satisfied by
// ErrNotExist as well as some syscall errors.
//
// This function predates errors.Is. It only supports errors returned by
// the os package. New code should use errors.Is(err, fs.ErrNotExist).
func IsNotExist(err error) bool {
    return underlyingErrorIs(err, ErrNotExist)
}

这个方法可以用来判断该err是否为os包中支持的文件/文件夹不存在的错误 

故 golang判断文件或文件夹是否存在时,需对方法os.Stat()返回的错误值进行判断:

  • 如果返回的错误为nil,说明文件或文件夹存在
  • 如果返回的错误类型使用os.IsNotExist() 判断为true,说明文件或文件夹不存在
  • 如果返回的错误为其它类型,则不确定是否在存在

此外,新代码好像不推荐用上述方式进行判断了

New code should use errors.Is(err, fs.ErrNotExist)