常用基础功能封装

package main

import (
   "bufio"
   "bytes"
   "encoding/json"
   "errors"
   "fmt"
   "io"
   "net/http"
   "os"
   "path/filepath"
   "strings"
   "time"
)

// FilepathAbs
// @description 获取当前文件所在目录,结尾不带“/”
// @return path string 当前文件所在目录,结尾不带“/”
// @return err error 错误对象,若没有发生错误则为nil
func FilepathAbs() (path string, err error) {
   path, err = filepath.Abs(".")
   path = strings.Replace(path, "\\", "/", -1)
   return
}

// FilepathDir
// @description 获取指定目录的上级目录,结尾不带“/”
// @param path string 指定目录
// @return father string 指定目录的上级目录,结尾不带“/”
func FilepathDir(path string) (father string) {
   father = filepath.Dir(path)
   father = strings.Replace(father, "\\", "/", -1)
   return
}

// FilePutContents
// @description 写入文件
// @param filename string 文件路径
// @param bytes []byte 写入内容
// @param flag int 写入方式,可选值:os.O_CREATE=不存在则创建|os.O_WRONLY=只写|os.O_APPEND=尾部追加
// @param perm os.FileMode 文件权限,示例:0644
// @return n int 写入内容长度,单位:字节
// @return err error 错误对象,若没有发生错误则为nil
func FilePutContents(filename string, bytes []byte, flag int, perm os.FileMode) (n int, err error) {
   var openFile *os.File
   openFile, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|flag, perm)
   if err != nil {
      return
   }

   // 关闭文件
   defer func(openFile *os.File) {
      _ = openFile.Close()
   }(openFile)

   // 写入文件
   writer := bufio.NewWriter(openFile)
   n, err = writer.Write(bytes)
   if err != nil {
      return
   }
   err = writer.Flush()

   return
}

// HttpGet
// @description 以GET方式发起HTTP请求
// @param url string 请求URL
// @return response []byte 响应内容
// @return err error 错误对象,若没有发生错误则为nil
func HttpGet(url string) (response []byte, err error) {
   var resp *http.Response
   resp, err = http.Get(url)
   if err != nil {
      return
   }

   // 关闭网络连接
   defer func(body io.ReadCloser) {
      _ = body.Close()
   }(resp.Body)

   // 状态码非200则请求失败
   if resp.StatusCode != http.StatusOK {
      err = errors.New(resp.Status) // resp.Status 示例值:404 Not Found
      return
   }

   // 将响应体读进buffer
   buffer := bytes.NewBuffer([]byte{})
   _, err = buffer.ReadFrom(resp.Body)
   if err != nil {
      return
   }

   response = buffer.Bytes()

   return
}

// IsDirExist
// @description 检查目录是否存在
// @param dir string 目录
// @return isDirExist bool true=目录存在|false=目录不存在
func IsDirExist(dir string) (isDirExist bool) {
   fileInfo, err := os.Stat(dir)
   if err != nil {
      return
   }

   isDirExist = fileInfo.IsDir()
   return
}

// IsMapKeyExist
// @description 检查map是否存在指定键名
// @param m map[string]any map数据
// @param key string 键名
// @return isMapKeyExist bool true=键名存在|false=键名不存在
func IsMapKeyExist(m map[string]any, key string) (isMapKeyExist bool) {
   _, isMapKeyExist = m[key]
   return
}

// JsonMarshal
// @description map转JSON
// @param m map[string]any map数据
// @return bytes []byte JSON
// @return err error 错误对象,若没有发生错误则为nil
func JsonMarshal(m map[string]any) (bytes []byte, err error) {
   bytes, err = json.Marshal(m)
   return
}

// JsonUnmarshal
// @description JSON转map
// @param bytes []byte JSON
// @return m map[string]any map数据
// @return err error 错误对象,若没有发生错误则为nil
func JsonUnmarshal(bytes []byte) (m map[string]any, err error) {
   err = json.Unmarshal(bytes, &m)
   return
}

// MkdirAll
// @description 创建目录(支持多层级)
// @param path string 目录(支持多层级)
// @param perm os.FileMode 目录权限,示例:0755
// @return err error 错误对象,若没有发生错误(目录已存在或成功创建目录)则为nil
func MkdirAll(path string, perm os.FileMode) (err error) {
   // 判断目录是否已存在
   if IsDirExist(path) {
      fmt.Printf("[DEBUG][INFO] 目录[%v]已存在,无需创建 \n", path)
      return
   }

   err = os.MkdirAll(path, perm)
   return
}

// TimeNow
// @description 获取当前的Unix时间戳(秒级,即10位数字)
// @return timeStamp int64 当前的Unix时间戳(秒级,即10位数字)
// @return err error 错误对象,若没有发生错误则为nil
func TimeNow() (timeStamp int64, err error) {
   var location *time.Location
   location, err = time.LoadLocation("Asia/Shanghai")
   if err != nil {
      return
   }

   timeStamp = time.Now().In(location).Unix()

   return
}

func main() {
   var err error

   // 获取当前的Unix时间戳(秒级,即10位数字)
   var timeStamp int64
   timeStamp, err = TimeNow()
   if err != nil {
      panic(err)
   }
   fmt.Printf("[DEBUG][INFO] 当前的Unix时间戳(秒级,即10位数字):%d \n", timeStamp)

   // 获取当前文件所在目录,结尾不带“/”
   var path string
   path, err = FilepathAbs()
   if err != nil {
      panic(err)
   }
   fmt.Printf("[DEBUG][INFO] 当前文件所在目录:%s \n", path)

   // 获取指定目录的上级目录,结尾不带“/”
   father := FilepathDir(path)
   fmt.Printf("[DEBUG][INFO] 当前文件所在目录上级目录:%s \n", father)

   // map转JSON
   var b []byte
   var m = map[string]any{}
   m["name"] = "张三"
   m["gender"] = "男"
   m["birth"] = 2003
   b, err = JsonMarshal(m)
   if err != nil {
      panic(err)
   }
   fmt.Printf("[DEBUG][INFO] map转JSON:%s \n", string(b))

   // JSON转map
   m = map[string]any{}
   m, err = JsonUnmarshal(b)
   if err != nil {
      panic(err)
   }
   fmt.Printf("[DEBUG][INFO] JSON转map:%v \n", m)

   // 检查目录是否存在(演示不存在的例子)
   dir := "C:/Windows/System32/foo"
   if IsDirExist(dir) {
      fmt.Printf("[DEBUG][INFO] 目录[%s]存在 \n", dir)
   } else {
      fmt.Printf("[DEBUG][INFO] 目录[%s]不存在 \n", dir)
   }
   // 检查目录是否存在(演示存在的例子)
   dir = "C:/Windows/System32/Microsoft"
   if IsDirExist(dir) {
      fmt.Printf("[DEBUG][INFO] 目录[%s]存在 \n", dir)
   } else {
      fmt.Printf("[DEBUG][INFO] 目录[%s]不存在 \n", dir)
   }

   // 创建目录(支持多层级)
   path, _ = FilepathAbs()
   dir = path + "/upload/yyyy/mm/dd"
   err = MkdirAll(dir, 0755)
   if err != nil {
      fmt.Printf("[DEBUG][INFO] 创建目录[%s]失败:%v \n", dir, err)
   } else {
      fmt.Printf("[DEBUG][INFO] 创建目录[%s]成功 \n", dir)
   }

   // 写入文件
   path, _ = FilepathAbs()
   filename := path + "/test.txt"
   var n int
   n, err = FilePutContents(filename, []byte("PHP是世界上最好の语言\n"), os.O_APPEND, 0644)
   if err != nil {
      fmt.Printf("[DEBUG][INFO] 写入文件[%s]失败:%v \n", filename, err)
   } else {
      fmt.Printf("[DEBUG][INFO] 写入文件[%s]成功,本次写入内容长度为%d字节 \n", filename, n)
      // 说明:一个字母和换行符占一个字节,一个汉字占三个字节
   }

   // 以GET方式发起HTTP请求
   api := "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"
   var response []byte
   response, err = HttpGet(api)
   if err != nil {
      fmt.Printf("[DEBUG][INFO] HTTP请求(以GET方式)出错:%v \n", err)
   } else {
      fmt.Printf("[DEBUG][INFO] HTTP请求(以GET方式)成功:%v \n", string(response))
      m = map[string]any{}
      m, err = JsonUnmarshal(response)

      // 判断请求响应内容是否含有errcode,有则将其打印出来
      if IsMapKeyExist(m, "errcode") {
         var errcode int64
         errcodeFloat64, ok := m["errcode"].(float64) // 重要提醒:Go语言会把网络请求返回的整数都当成float64,断言时务必注意
         if ok {
            errcode = int64(errcodeFloat64)
            fmt.Printf("[DEBUG][INFO]   -- errcode = %d \n", errcode)
         }
      }

      // 判断请求响应内容是否含有errmsg,有则将其打印出来
      if IsMapKeyExist(m, "errmsg") {
         errmsg, ok := m["errmsg"].(string)
         if ok {
            fmt.Printf("[DEBUG][INFO]   -- errmsg = %s \n", errmsg)
         }
      }
   }
}

Copyright © 2024 码农人生. All Rights Reserved