package CommonUtil import ( "bufio" "bytes" "crypto/md5" "encoding/binary" "encoding/hex" "encoding/json" "errors" "fmt" uuid "github.com/satori/go.uuid" "io" "log" "math/rand" "os" "os/exec" "path/filepath" "regexp" "strconv" "strings" "time" "unsafe" ) /** 功能:获取UUID 作者:黄海 时间:2020-02-03 */ func GetUUID() string { u2 := strings.ToUpper(uuid.NewV4().String()) return u2 } /** 功能:判断是不是合法的日期格式 作者:黄海 时间:2020-03-23 */ func IsDate(date string) bool { _, err := time.Parse("2006-01-02 15:04:05", date) if err != nil { return false } else { return true } } /** 功能:从一个数据库的查询返回结果中获取指定字段的IDS 作者:黄海 时间:2020-02-14 */ func SelectIdsFromMapInterface(list []map[string]interface{}, key string) []string { var ids []string for i := 0; i < len(list); i++ { switch list[i][key].(type) { case string: ids = append(ids, list[i][key].(string)) break case int64: ids = append(ids, strconv.FormatInt(list[i][key].(int64), 10)) } } return ids } /** 功能:将一个数据库查询返回结果中的某一列,形成字典 作者:黄海 时间:2020-02-14 */ func PutSelectResultToMapByField(list []map[string]interface{}, field string) map[string]interface{} { _dict := make(map[string]interface{}) for i, _ := range list { record := list[i] switch record[field].(type) { case int64: _dict[strconv.FormatInt(record[field].(int64), 10)] = 1 default: _dict[record[field].(string)] = 1 } } return _dict } /** 功能:通过字典获取字符串数组 作者:黄海 时间:2020-02-14 */ func GetArrayByMap(_dict map[string]interface{}) []string { Ids := make([]string, 0, len(_dict)) for k := range _dict { Ids = append(Ids, k) // } return Ids } /** 功能:将数据库返回的查询结果映射成字典,用于扩展字段 作者:黄海 时间:2020-02-14 */ func ConvertMapInterfaceToMapByField(list []map[string]interface{}, key string, value string) map[string]string { _map := make(map[string]string) for i, _ := range list { var areaTypeId string switch list[i][key].(type) { case int64: areaTypeId = strconv.FormatInt(list[i][key].(int64), 10) default: areaTypeId = list[i][key].(string) } switch list[i][value].(type) { case int64: _map[areaTypeId] = strconv.FormatInt(list[i][value].(int64), 10) default: _map[areaTypeId] = list[i][value].(string) } } return _map } /** 功能:扩展数据库查询结果集 作者:黄海 时间:2020-02-14 */ func ExtendList(list *[]map[string]interface{}, _map map[string]string, key string, value string) { for i, _ := range *list { sourceRecord := (*list)[i] var a string switch sourceRecord[key].(type) { case int64: a = strconv.FormatInt(sourceRecord[key].(int64), 10) default: a = sourceRecord[key].(string) } sourceRecord[value] = _map[a] } } /** 功能:删除字符串多余的空格 作者:黄海 时间:2020-01-20 */ func DeleteExtraSpace(s string) string { //删除字符串中的多余空格,有多个空格时,仅保留一个空格 s1 := strings.Replace(s, " ", " ", -1) //替换tab为空格 regstr := "\\s{2,}" //两个及两个以上空格的正则表达式 reg, _ := regexp.Compile(regstr) //编译正则表达式 s2 := make([]byte, len(s1)) //定义字符数组切片 copy(s2, s1) //将字符串复制到切片 spcIndex := reg.FindStringIndex(string(s2)) //在字符串中搜索 for len(spcIndex) > 0 { //找到适配项 s2 = append(s2[:spcIndex[0]+1], s2[spcIndex[1]:]...) //删除多余空格 spcIndex = reg.FindStringIndex(string(s2)) //继续在字符串中搜索 } return string(s2) } //删除字符串中的空白行 func DeleteBlankString(str string) string { var arr = strings.Split(str, "\r\n") var resultStr = "" for i := 0; i < len(arr); i++ { if len(strings.Replace(strings.Replace(arr[i], " ", "", -1), "\t", "", -1)) > 0 { resultStr += arr[i] + "\r\n" } } return resultStr } //删除文件中空白行 func DeleteBlankFile(srcFilePah string, destFilePath string) error { srcFile, err := os.OpenFile(srcFilePah, os.O_RDONLY, 0666) defer srcFile.Close() if err != nil { return err } srcReader := bufio.NewReader(srcFile) destFile, err := os.OpenFile(destFilePath, os.O_WRONLY|os.O_CREATE, 0666) defer destFile.Close() if err != nil { return err } for { str, err := srcReader.ReadString('\n') if err != nil { if err == io.EOF { fmt.Print("The file end is touched.") break } else { return err } } if strings.HasSuffix(str, " \r\n") { continue } if strings.HasPrefix(str, "\r\n") { continue } fmt.Println(len(str)) fmt.Print(str) destFile.WriteString(str) } return nil } //如果是小写字母, 则变换为大写字母 func StrFirstToUpper(str string) string { var upperStr string vv := []rune(str) // 后文有介绍 for i := 0; i < len(vv); i++ { if i == 0 { if vv[i] >= 97 && vv[i] <= 122 { // 后文有介绍 vv[i] -= 32 // string的码表相差32位 upperStr += string(vv[i]) } else { return str } } else { upperStr += string(vv[i]) } } return upperStr } //如果是大写字母, 则变换为小写字母 func StrFirstToLower(str string) string { if len(str) < 1 { return "" } strArry := []rune(str) if strArry[0] >= 65 && strArry[0] <= 90 { strArry[0] += 32 } return string(strArry) } /** 功能:获取蛇形命名的字符串 作者:黄海 时间:2020-01-22 */ func GetSnakeCaseStr(str string) string { array := strings.Split(str, "_") var result string for i := 0; i < len(array); i++ { result = result + strings.ToUpper(array[i][0:1]) + array[i][1:] } return result } const ( // 可自定义盐值 TokenSalt = "DsideaL4r5t6y7u" ) func MD5(data []byte) string { _md5 := md5.New() _md5.Write(data) return hex.EncodeToString(_md5.Sum([]byte(""))) } //isSymbol表示有无符号 func BytesToInt(b []byte, isSymbol bool) (int, error) { if isSymbol { return BytesToIntS(b) } return bytesToIntU(b) } //字节数(大端)组转成int(无符号的) func bytesToIntU(b []byte) (int, error) { if len(b) == 3 { b = append([]byte{0}, b...) } bytesBuffer := bytes.NewBuffer(b) switch len(b) { case 1: var tmp uint8 err := binary.Read(bytesBuffer, binary.BigEndian, &tmp) return int(tmp), err case 2: var tmp uint16 err := binary.Read(bytesBuffer, binary.BigEndian, &tmp) return int(tmp), err case 4: var tmp uint32 err := binary.Read(bytesBuffer, binary.BigEndian, &tmp) return int(tmp), err default: return 0, fmt.Errorf("%s", "BytesToInt bytes lenth is invaild!") } } //字节数(大端)组转成int(有符号) func BytesToIntS(b []byte) (int, error) { if len(b) == 3 { b = append([]byte{0}, b...) } bytesBuffer := bytes.NewBuffer(b) switch len(b) { case 1: var tmp int8 err := binary.Read(bytesBuffer, binary.BigEndian, &tmp) return int(tmp), err case 2: var tmp int16 err := binary.Read(bytesBuffer, binary.BigEndian, &tmp) return int(tmp), err case 4: var tmp int32 err := binary.Read(bytesBuffer, binary.BigEndian, &tmp) return int(tmp), err default: return 0, fmt.Errorf("%s", "BytesToInt bytes lenth is invaild!") } } //整形转换成字节 func IntToBytes(n int, b byte) ([]byte, error) { switch b { case 1: tmp := int8(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, &tmp) return bytesBuffer.Bytes(), nil case 2: tmp := int16(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, &tmp) return bytesBuffer.Bytes(), nil case 3, 4: tmp := int32(n) bytesBuffer := bytes.NewBuffer([]byte{}) binary.Write(bytesBuffer, binary.BigEndian, &tmp) return bytesBuffer.Bytes(), nil } return nil, fmt.Errorf("IntToBytes b param is invaild") } /** 功能:生成一个随机盐 作者: 黄海 时间:2020-02-18 */ func GetRandomSalt() string { return GetRandomString(8) } //生成随机字符串 func GetRandomString(l int) string { str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" bytes := []byte(str) var result []byte r := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < l; i++ { result = append(result, bytes[r.Intn(len(bytes))]) } return string(result) } /** 功能:获取当前的时间戳,精确度纳秒 作者:黄海 时间:2020-02-18 */ func GetCurrentTimestamp() int64 { return time.Now().UnixNano() } /** 功能:获取当前的时间字符串 作者:黄海 时间:2020-02-21 */ func GetCurrentTime() string { timeStr := time.Now().Format("2006-01-02 15:04:05") //当前时间的字符串,2006-01-02 15:04:05据说是golang的诞生时间,固定写法 return timeStr } /** 功能:将Json格式的字符串转为map 作者:吴缤 日期:2020-02-21 */ func JsonStrToMap(jsonStr string) (map[string]interface{}, error) { var _map map[string]interface{} err := json.Unmarshal([]byte(jsonStr), &_map) if err == nil { if _map["code"] != nil { var _code = int(_map["code"].(float64)) _map["code"] = _code } return _map, nil } else { return nil, err } } /* 功能:返回当前GO文件所在的目录 */ func GetCurrentDirectory() string { directory, _ := os.Getwd() return directory } // 判断所给路径文件/文件夹是否存在 func Exists(path string) bool { _, err := os.Stat(path) //os.Stat获取文件信息 if err != nil { if os.IsExist(err) { return true } return false } return true } /** 功能:将int数据类型转为int64 作者:黄海 时间:2020-02-18 */ func ConvertIntToInt64(i int) int64 { s := strconv.Itoa(i) s64, _ := strconv.ParseInt(s, 10, 64) return s64 } /** 功能:将字符串转为整数 作者:黄海 时间:2020-04-17 */ func ConvertStringToInt(s string) int { i, _ := strconv.Atoi(s) return i } /** 功能:将字符串转为int32整数 作者:黄海 时间:2020-04-17 */ func ConvertStringToInt32(s string) int32 { i, _ := strconv.Atoi(s) return int32(i) } /** 功能:将字符串转为整数64 作者:黄海 时间:2020-04-17 */ func ConvertStringToInt64(s string) int64 { i, _ := strconv.ParseInt(s, 10, 64) return i } /** 功能:将整数转为字符串 作者:黄海 时间:2020-04-17 */ func ConvertIntToString(i int) string { s := strconv.Itoa(i) return s } /** 功能:将整数64转为字符串 作者:黄海 时间:2020-04-17 */ func ConvertInt64ToString(i int64) string { s := strconv.FormatInt(i, 10) return s } /** 功能:将int64转为int 作者:黄海 时间:2020-04-23 */ func ConvertInt64ToInt(int64Num int64) int { // 将 int64 转化为 int intNum := *(*int)(unsafe.Pointer(&int64Num)) return intNum } /** 功能:将JSON字符串转化为map数组 作者: 黄海 时间:2020-04-17 */ func ConvertJsonStringToMapArray(data string) []map[string]interface{} { var m = make([]map[string]interface{}, 0) str := []byte(data) json.Unmarshal(str, &m) return m } /** 功能:判断目录是否存在 */ func PathExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } //获取文件修改时间 返回unix时间戳 func GetFileModTime(path string) int64 { f, err := os.Open(path) if err != nil { log.Println("open file error") return time.Now().Unix() } defer f.Close() fi, err := f.Stat() if err != nil { log.Println("stat fileinfo error") return time.Now().Unix() } return fi.ModTime().Unix() } //自己编写一个函数,接收两个文件路径 srcFileName dstFileName func CopyFile(srcFileName string, dstFileName string) (written int64, err error) { srcFile, err := os.Open(srcFileName) if err != nil { fmt.Printf("open file err = %v\n", err) return } defer srcFile.Close() //打开dstFileName dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0755) if err != nil { fmt.Printf("open file err = %v\n", err) return } defer dstFile.Close() return io.Copy(dstFile, srcFile) } /** 功能:将在系统中使用的类列表(比如:BasePerson)还原为数据库中的表名:t_base_person 作者:黄海 时间:2020-05-30 */ func ConvertTrueTableName(tableName string) string { var result = "t" for _, char := range []rune(tableName) { if int(char) >= 65 && int(char) <= 90 { result += "_" + strings.ToLower(string(char)) } else { result += string(char) } } return result } /** 功能:带回显的执行DOS命令 作者:黄海 时间:2020-05-18 */ func Exec(name string, args ...string) error { cmd := exec.Command(name, args...) stderr, _ := cmd.StderrPipe() stdout, _ := cmd.StdoutPipe() if err := cmd.Start(); err != nil { log.Println("exec the cmd ", name, " failed") return err } // 正常日志 logScan := bufio.NewScanner(stdout) go func() { for logScan.Scan() { log.Println(logScan.Text()) } }() // 错误日志 errBuf := bytes.NewBufferString("") scan := bufio.NewScanner(stderr) for scan.Scan() { s := scan.Text() log.Println("", s) errBuf.WriteString(s) errBuf.WriteString("\n") } // 等待命令执行完 cmd.Wait() if !cmd.ProcessState.Success() { // 执行失败,返回错误信息 return errors.New(errBuf.String()) } return nil } /** 功能:数组中是否存在某个字符串 作者:黄海 时间:2020-05-30 */ func IsContainString(items []string, item string) bool { for _, eachItem := range items { if eachItem == item { return true } } return false } func IsContainInt32(items []int32, item int32) bool { for _, eachItem := range items { if eachItem == item { return true } } return false } /** 功能:获取当前路径 作者:黄海 时间:2020-06-02 */ func GetCurrentPath() string { dir, _ := os.Getwd() dir = strings.ReplaceAll(dir, "\\", "/") return dir } /** 功能:获取当前工作目录的父路径 作者:黄海 时间:2020-06-02 */ func GetCurrentParentPath()string{ return GetParentPath(GetCurrentPath()) } /** 功能:返回上一级目录 */ func GetParentPath(directory string) string { return strings.Replace(filepath.Dir(directory), "\\", "/", -1) }