golang 常用工具包

这篇博客汇总了Golang编程中常用的工具包,包括convertoper、fileoper、otheroper和reflectoper。通过这篇文章,读者可以方便地查阅和学习这些工具包的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

convertoper

package convertoper

import (
	"encoding/binary"
	"reflect"
	"unsafe"
)


//byte数组转 int32
func BytesToInt32(buf []byte) int32 {
	return int32(binary.BigEndian.Uint32(buf))
}
//byte数组转 int64
func BytesToInt64(buf []byte) int64 {
	return int64(binary.BigEndian.Uint64(buf))
}

//https://www.cnblogs.com/ghost240/p/3739785.html
//string 转换成byte[]
func StringTobytes(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s))
	h := [3]uintptr{x[0], x[1], x[1]}
	return *(*[]byte)(unsafe.Pointer(&h))
}
func SliceToString(b []byte) (s string) {
	pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b))
	pstring := (*reflect.StringHeader)(unsafe.Pointer(&s))
	pstring.Data = pbytes.Data
	pstring.Len = pbytes.Len
	return
}

//利用反射来转切片为string
func SliceToStringByintefce(v interface{}) (s string) {
	/*
		if reflect.TypeOf(v).Kind()!=reflect.Slice {
			otheroper.ErrorMsg(errors.New("当前类型不是Slice"),2,"")
			return
		}
	*/

	return string(reflect.ValueOf(v).Bytes())
}

//https://www.cnblogs.com/Detector/p/9686443.html
//  字符首字母大写
func FirstUpper(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 {
				//fmt.Println("Not begins with lowercase letter,")
				return str
			}
		} else {
			upperStr += string(vv[i])
		}
	}
	return upperStr
}

fileoper

package fileoper

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"tools/otheroper"
)

//复制文件
func Copy(src, dst string) (int64, error) {

	sourceFileStat, err := os.Stat(src)
	if err != nil {
		return 0, err
	}

	if !sourceFileStat.Mode().IsRegular() {
		return 0, fmt.Errorf("%s is not a regular file", src)
	}

	source, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer source.Close()

	destination, err := os.Create(dst)
	if err != nil {
		return 0, err
	}

	defer destination.Close()
	nBytes, err := io.Copy(destination, source)

	return nBytes, err
}



// 根据 文件 路径 找到文件,并打开当前阅读进度
func GetbookBypath(path string, progress float64) string {
	//打开文件
	file, err := os.OpenFile(path, os.O_RDWR, os.ModePerm)

	defer func() { file.Close() }()

	otheroper.ErrorMsg(err, 2, "oper file error:")

	//Stat返回一个描述name指定的文件对象的FileInfo
	infos, _ := os.Stat(path)
	size := infos.Size()
	//当前用户已读文件大小
	currentProgress := progress * float64(size)
	fmt.Printf("当前文件进度为: %v%%, 文件有 %v 个字节 ,文件总大小为 %.2f mb \n", progress*float64(100), size, float64(size)/float64(1048576))

	by := []byte{2}
	//Seek设置下一次读/写的位置。offset为相对偏移量,
	// 而whence决定相对位置:0为相对文件开头,1为相对当前位置,2为相对文件结尾。
	// 它返回新的偏移量(相对开头)和可能的错误。
	var bf strings.Builder
	file.Seek(int64(currentProgress), io.SeekStart)
	for i := 0; i <= 1000; i++ {
		file.Read(by)
		bf.Write(by)
	}

	return bf.String()
}

//比较文件类型是否匹配 其实最好的方法是有 文件头来 比较文件类型
func Comperext(filename string, fileext string, ) string {
	var result string

	if fileext != "*" {
		//如果文件后缀 等于指定文件的类型
		if fileext == filepath.Ext(filename) {
			result = filename
		}
	} else {
		result = filename
	}
	return result
}
//要不要返回目录
func GetContanisDir(needDir bool,f os.FileInfo,fileext string)  string {
	var result string

	//要目录
	if needDir {
		//是个目录
		if f.IsDir() {
			result =f.Name()
		} else {
			result = Comperext(f.Name(), fileext)
		}

	} else {
		//不要目录
		if !f.IsDir() {
			//是个文件
			result = Comperext(f.Name(), fileext)

		}
	}
	return result
}
//获取当前目录下的文件,
// path 文件夹路径
// dept 0 当前文件夹下的文件
//      1 当前文件夹所有文件  包含子文件夹下面的文件
// fileext 获取指定文件的类型,如 文本文件 .txt, 任意文件  *
// needDir 要不要返回目录 信息
func GetAllFiles(path string, dept int, fileext string, needDir bool) []string {
	filesSlice := make([]string, 0)

	switch dept {
	case 0:

		infos, _ := ioutil.ReadDir(path)
		for _, f := range infos {

			result:=GetContanisDir(needDir,f,fileext)
			if len(result)>0 {
				filesSlice = append(filesSlice, result)
			}

		}

	case 1:
		root:=0
       //walk 函数会把 root 根路径包含在里面,
       // 就像 tree一样 因此第一次进来时就不返回root了
		err := filepath.Walk(path,
			func(filename string, info os.FileInfo, err error) error {
				otheroper.ErrorMsg(err, 2, "访问文件错误")
				if root>0 {
					result:=GetContanisDir(needDir,info,fileext)
					if len(result)>0 {
						filesSlice = append(filesSlice, result)
					}
				}
				root=1

				return nil
			})
		otheroper.ErrorMsg(err, 2, "访问文件错误")

	}

	return filesSlice

}

otheroper

package otheroper

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
)


func ComputeHmac256(message string, secret string) string {
	key := []byte(secret)
	h := hmac.New(sha256.New, key)
	h.Write([]byte(message))
	return base64.StdEncoding.EncodeToString(h.Sum(nil))
}


package otheroper

import (
	"fmt"
	"path/filepath"
	"runtime"
)
//depth o 为 当前ErrorMsg ,2为错误产生的函数
func ErrorMsg(err error,depth int,msg string)bool  {

	if err != nil {
		caller(depth,err.Error()+";"+msg)
		return false
	}

	return true
}

//Caller报告当前go程调用栈所执行的函数的文件和行号信息。实参skip为上溯的栈帧数,0表示Caller的调用者
func caller(depth int,msg string)  {
	_,file,line,ok:=runtime.Caller(depth)

	if !ok {
		msg= "暂未获取到函数信息"
	}else {
		msg= fmt.Sprintf("当前方法在 %v 文件中,在 %v 行中. \n错误信息为: 【%v】  \n",filepath.Base(file),line,msg)
	}


	fmt.Printf(msg)
}

package otheroper
//拆分4份
//fmt.Println("println:",SplitArray(arr1,4))
//数组平分
func SplitArray(arr []interface{}, num int) ([][]interface{}) {
	max := int(len(arr))
	if max < num {
		return nil
	}
	var segmens =make([][]interface{},0)
	quantity:=max/num
	end:=int(0)
	for i := int(1); i <= num; i++ {
		qu:=i*quantity
		if i != num {
			segmens= append(segmens,arr[i-1+end:qu])
		}else {
			segmens= append(segmens,arr[i-1+end:])
		}
		end=qu-i
	}
	return segmens
}

package otheroper

import (
	"math/rand"
	"strings"
	"time"
)
//就是拼接字符串,
func GetBuildStr(str... string )string  {
	var build strings.Builder
	for _,v:= range str{
		build.WriteString(v)
	}
	return build.String()
}
//根据等级生成随机数,level 越大 生成随机数越大
func GetRandBylevel(level int) int {
	rand.Seed(time.Now().Unix())
	return rand.Intn(level*10)

}
//生成一定范围内随机数,
// isLoop 是否在循环之内,如果在,请设为ture 因为程序太快了,会生成一样的数字
func RandInt64(min, max int64,isLoop bool) int64 {
	if min >= max || min == 0 || max == 0 {
		return max
	}
	if isLoop {
		time.Sleep(10*time.Nanosecond)
	}

	rand.Seed(time.Now().UnixNano())
	return rand.Int63n(max-min) + min
}

reflectoper

package reflectoper

import (
	"errors"
	"reflect"
	"strconv"
	"strings"
)

type ModeObj struct {
	Field      string //多个字段字符串,以,分隔
	StructName string //结构名称、
	ValueStrs  string //多个值的字符串,以,分隔
}


//获取结构多个字段字符串,以, 分隔,以及返回结构名称
func GetStructMsg(value interface{}) (modeobj ModeObj, err error) {

	t := reflect.TypeOf(value)
	v := reflect.ValueOf(value)



	if t.NumField() == 0 {
		return modeobj, errors.New(" you struct Field  length not nil")
	}
	//写入字段
	var bf strings.Builder
	//写入值
	var bfv strings.Builder
	for i := 0; i < t.NumField(); i++ {
		// strings.Join([]string{t.Field(i).Name} ,",")
		bf.WriteString(t.Field(i).Name)
		bf.WriteString(",")
		c := v.Field(i)
		//获取值
		if c.Kind() != reflect.Invalid {

			switch c.Kind() {
			case reflect.String:
				bfv.WriteString(`"`)
				bfv.WriteString(c.String())
				bfv.WriteString(`"`)

			case reflect.Int:
				bfv.WriteString(strconv.FormatInt(c.Int(), 10))

			case reflect.Float32:
				fl32 := strconv.FormatFloat(c.Float(), 'f', -1, 32)
				bfv.WriteString(fl32)

			case reflect.Float64:
				fl64 := strconv.FormatFloat(c.Float(), 'f', -1, 64)

				bfv.WriteString(fl64)

			}

			bfv.WriteString(",")

		}

	}
	bs := bf.String()
	modeobj.Field = bs[0 : len(bs)-1]
	modeobj.StructName = t.Name()

	bs = bfv.String()
	modeobj.ValueStrs = bs[0 : len(bs)-1]
	return modeobj, nil

}

好了,基本上以前的文章 所调用的工具包,就在该篇文章中,可以查阅到,
如果亲,觉得可以,给个,三连把,啊呸 ,给个赞吧,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值