1 Star 0 Fork 0

xiongqb/go-utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
common.go 10.74 KB
一键复制 编辑 原始数据 按行查看 历史
xiongqb 提交于 1年前 . macOS开机启动
package common
import (
"container/list"
"fmt"
"log"
"math"
"os"
"reflect"
"runtime"
"strconv"
"strings"
"time"
)
var (
IsWindows = runtime.GOOS == "windows"
IsLinux = runtime.GOOS == "linux"
IsMac = runtime.GOOS == "darwin"
)
// InitLog 初始化日志设置
//
// followExe 否跟随执行文件,true日志文件在执行文件目录下,false则在用户目录下。
//
// names 可以不设置,多个将会拼接 尽量只是文件名
//
// fatal系列函数会在写入日志信息后调用os.Exit(1)。Panic系列函数会在写入日志信息后panic。
//
// log.Fatalln("fatal系列函数会在写入日志信息后调用os.Exit(1)")
//
// log.Panicln("执行后会自动触发一个异常")
func InitLog(followExe bool, names ...string) {
fmt.Println("当前日志环境(GO_ENV)")
goEnv := os.Getenv("GO_ENV")
fmt.Println("当前日志环境(GO_ENV)", "["+goEnv+"]")
log.SetFlags(log.Lshortfile | log.Lmicroseconds | log.Ldate)
if goEnv == "dev" {
return
}
fileRoot := ""
if followExe {
fileRoot = FileGetCurrentDir()
} else {
fileRoot = FileGetUserDir()
}
file := ""
if len(names) == 0 {
fullFilename := FileGetFilename(FileGetExecFile())
fmt.Println("fullFilename", fullFilename)
fileName := "go-" + FileGetName(fullFilename) + ".log"
file = FileOf(fileRoot, "logs", fileName)
} else {
filePath := FileOf(names...)
// 绝对路径
if FileIsAbsolutePath(filePath) {
file = filePath
} else {
// 相对路径,用户目录下
file = FileOf(fileRoot, filePath)
}
}
fmt.Println("初始化日志文件", file)
if !FileExists(file) {
dir := FileGetParentDir(file)
//创建目录
if !FileExists(dir) {
FileCreateDirs(dir)
}
}
logFile, err := os.OpenFile(file, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Println("open log file failed, err:", err)
return
}
log.SetOutput(logFile)
}
func ThrowException(errors ...any) {
panic(fmt.Sprintf("%v", errors))
}
// Debounce 防抖函数
func Debounce(delay time.Duration, fn func()) func() {
t := time.NewTimer(delay)
quit := make(chan struct{})
return func() {
if !t.Stop() {
<-t.C
}
go func() {
select {
case <-quit:
case <-time.After(delay):
fn()
}
}()
t.Reset(delay)
}
}
type Debouncer struct {
fn func()
interval time.Duration
timer *time.Timer
}
func NewDebouncer(interval time.Duration, fn func()) *Debouncer {
return &Debouncer{
fn: fn,
interval: interval,
timer: time.NewTimer(interval),
}
}
func (d *Debouncer) Reset() {
if !d.timer.Stop() {
select {
case <-d.timer.C:
default:
}
}
d.timer.Reset(d.interval)
go func() {
select {
case <-d.timer.C:
d.fn()
case <-time.After(d.interval):
}
}()
}
////GBK转utf8的方法
//type Charset string
//
//const (
// UTF8 = Charset("UTF-8")
// GB18030 = Charset("GB18030")
//)
//
//func ConvertByte2String(byte []byte, charset Charset) string {
// //需要导入import "golang.org/x/text/encoding/simplifiedchinese"
// var str string
// switch charset {
// case GB18030:
// decodeBytes, _ := simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
// str = string(decodeBytes)
// case UTF8:
// fallthrough
// default:
// str = string(byte)
// }
//
// return str
//}
// IsInstanceOf sample variables
//
// someString :="Some String"
// someFloat := float32(2.4)
// someStruct1 := SomeStruct1{}
// someStruct2 := SomeStruct2{}
// someStruct1Ptr := &SomeStruct1{}
// // primitive string
// fmt.Println("string <-> *string \\t\\t", IsInstanceOf(someString, (*string)(nil))) //false
// fmt.Println("*string <-> *string \\t\\t", IsInstanceOf(&someString, (*string)(nil))) //true
// // primitive float32
// fmt.Println("float32 <-> *float32 \\t\\t", IsInstanceOf(someFloat, (*float32)(nil))) //false
// fmt.Println("*float32 <-> *float32 \\t\\t", IsInstanceOf(&someFloat, (*float32)(nil))) //true
// // structure
// fmt.Println("SomeStruct1 <-> *SomeStruct1 \\t", IsInstanceOf(someStruct1, (*SomeStruct1)(nil))) //false
// fmt.Println("*SomeStruct1 <-> *SomeStruct1 \\t", IsInstanceOf(&someStruct1, (*SomeStruct1)(nil))) //true
// fmt.Println("*SomeStruct2 <-> *SomeStruct1 \\t", IsInstanceOf(&someStruct2, (*SomeStruct1)(nil))) //false
// fmt.Println("*SomeStruct1 <-> *SomeStruct1 \\t", IsInstanceOf(someStruct1Ptr, (*SomeStruct1)(nil))) //true
func IsInstanceOf(objectPtr, typePtr interface{}) bool {
return reflect.TypeOf(objectPtr) == reflect.TypeOf(typePtr)
}
func InstanceOf(objectPtr interface{}) string {
return reflect.TypeOf(objectPtr).String()
}
func ConfigMapReadFile(fileConfig string) map[string]string {
return TxtToConfigMapBy(FileRead(fileConfig), "\n", "@=")
}
func ConfigMapWriteFile(configMap map[string]string, fileConfig string) {
contentConfig := ""
// 遍历map
for key, value := range configMap {
contentConfig += fmt.Sprintf("%s@=%s\n", key, value)
}
FileWrite(fileConfig, contentConfig)
}
// TxtToConfigMap 将config 通过 \n 分成lines 再通过 @= 分成key-value 。#开头将被跳过
func TxtToConfigMap(config string) map[string]string {
return TxtToConfigMapBy(config, "\n", "@=")
}
// TxtToConfigMapBy 将config 通过 firstSplit 分成lines 再通过 secondSplit 分成 key-value。#开头将被跳过
func TxtToConfigMapBy(config, firstSplit, secondSplit string) map[string]string {
lines := StrSplit(config, firstSplit)
size := len(lines)
// 创建一个空的 Map[key]value
// 创建一个初始容量为 10 的 Map
m := make(map[string]string, 2)
for i := 0; i < size; i++ {
line := StrTrim(lines[i])
if len(line) == 0 {
continue
} else if StrStartsWith(line, "#") {
continue
}
arr := StrSplit(line, secondSplit)
if len(arr) == 2 {
m[arr[0]] = arr[1]
}
}
fmt.Println("TxtToConfigMap_ map size = ", len(m))
return m
}
// ArgsToConfigMap 将参数数组解析成map 只有-key=value会被解析,如:-s=123
func ArgsToConfigMap(args ...string) map[string]string {
size := len(args)
// 创建一个空的 Map[key]value
// 创建一个初始容量为 10 的 Map
m := make(map[string]string, 2)
size1 := 0
key := ""
for i := 0; i < size; i++ {
line := StrTrim(args[i])
if len(line) == 0 {
continue
} else if !StrStartsWith(line, "-") {
continue
}
arr := StrSplit(line, "=")
size1 = len(arr)
if size1 > 0 {
key = strings.Replace(arr[0], "-", "", -1)
if size1 == 1 {
m[key] = "true"
} else {
m[key] = arr[1]
}
}
}
return m
}
func ListToArrayStr(lst *list.List) []string {
size := lst.Len()
tmp := make([]string, size)
i := 0
for e := lst.Front(); e != nil; e = e.Next() {
tmp[i] = fmt.Sprintf("%v", e.Value)
i++
}
return tmp
}
func ListToArrayInt(lst *list.List) []int {
size := lst.Len()
tmp := make([]int, size)
i := 0
for e := lst.Front(); e != nil; e = e.Next() {
parseInt, err := strconv.ParseInt(fmt.Sprintf("%v", e.Value), 10, 0)
if err != nil {
ThrowException("ListToArrayInt", e.Value, err)
}
tmp[i] = int(parseInt)
i++
}
return tmp
}
func TestIntRange() {
//see https://blog.csdn.net/u011582922/article/details/121732193
//go语言中的int的大小是和操作系统位数相关的;
//如果是32位操作系统,int类型的大小就是4字节;
//如果是64位操作系统,int类型的大小就是8个字节
// 不同int类型的取值范围
fmt.Println("不同int类型的取值范围(有符号):")
fmt.Println("int8:", math.MinInt8, "~", math.MaxInt8) //int8: -128 ~ 127
fmt.Println("int16:", math.MinInt16, "~", math.MaxInt16) //int16: -32768 ~ 32767
fmt.Println("int32:", math.MinInt32, "~", math.MaxInt32) //int32: -2147483648 ~ 2147483647
fmt.Println("int64:", math.MinInt64, "~", math.MaxInt64) //int64: -9223372036854775808 ~ 9223372036854775807
fmt.Println("int:", math.MinInt, "~", math.MaxInt) //int: -9223372036854775808 ~ 9223372036854775807
fmt.Println()
fmt.Println("不同int类型的取值范围(无符号):")
fmt.Println("uint8:", 0, "~", math.MaxUint8) //uint8: 0 ~ 255
fmt.Println("uint16:", 0, "~", math.MaxUint16) //uint16: 0 ~ 65535
fmt.Println("uint32:", 0, "~", math.MaxUint32) //uint32: 0 ~ 4294967295
//fmt.Println("uint64:", 0, "~", math.MaxUint64) //uint64: 0 ~ 18446744073709551615 因fmt.Println无法打印而报错?
//fmt.Println("uint:", 0, "~", math.MaxUint) //uint: 0 ~ 18446744073709551615 因fmt.Println无法打印而报错?
}
func NotifyError(content string) {
NotifyWinBat("错误通知", content, ICON_ERROR)
}
func NotifyInfo(content string) {
NotifyWinBat("消息通知", content, ICON_INFO)
}
func Notify(title string, content string) bool {
//icon := "C:\\Projects\\workspace-idea\\JavaFX\\javasw-tools\\src\\main\\resources\\success.png"
log.Println(runtime.GOOS)
switch runtime.GOOS {
case "darwin":
NotifyMac(title, content)
case "linux":
case "windows":
//fmt.Println(notifyWinByTransient(title, content, icon))
//fmt.Println(CmdAndChangeDir("","growlnotify", "/i:", icon, "/t:", title, content))
NotifyWinBat(title, content, ICON_INFO)
}
return true
}
func NotifyMac(title, message string) string {
//osascript -e 'display notification "下午3点会议室A开会,不要迟到!" with title "会议提醒"'
content := fmt.Sprintf(`'display notification "%s" with title "%s"'`, message, title)
run := CmdDirRun("", "osascript", "-e", content)
return run
}
// func notifyWinByTransient(title string, text string, iconPath string) *exec.Cmd {
// return exec.Command("growlnotify", "/i:", iconPath, "/t:", title, text)
// }
// // Causes the notification to stick around until clicked.
// func notifyWin(title string, text string, iconPath string) *exec.Cmd {
// return exec.Command("growlnotify", "/i:", iconPath, "/t:", title, text, "/s", "true", "/p", "2")
// }
type NotifyIcon string
const (
ICON_INFO = NotifyIcon("information")
ICON_ERROR = NotifyIcon("error")
ICON_WARNING = NotifyIcon("warning")
)
func NotifyWinBat(title, message string, icon NotifyIcon) string {
//https://stackoverflow.com/questions/39535937/what-is-the-notify-send-equivalent-for-windows
//http://vaskovsky.net/notify-send/
tmp := "chcp 65001\n\r" +
"for /f \"delims=\" %%a in ('powershell -c \"[reflection.assembly]::loadwithpartialname('System.Windows.Forms');" +
"[reflection.assembly]::loadwithpartialname('System.Drawing');$notify = new-object system.windows.forms.notifyicon;" +
"$notify.icon = [System.Drawing.SystemIcons]::%$Icon%;$notify.visible = $true;" +
"$notify.showballoontip(10,'%$Titre%','%$Message%',[system.windows.forms.tooltipicon]::None)\"') do (set $=)"
tmp = strings.Replace(tmp, "%$Icon%", string(icon), -1)
tmp = strings.Replace(tmp, "%$Titre%", title, -1)
tmp = strings.Replace(tmp, "%$Message%", message, -1)
//bat := File(FileGetCurrentDir(),fmt.Sprintf("%d",time.Now().Unix()), ".bat")
bat := FileOf(FileGetCurrentDir(), ToString(time.Now().Unix()), ".bat")
FileWrite(bat, tmp)
run := CmdDirRun("", bat)
FileDelete(bat)
return run
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/xiongqb/go-utils.git
git@gitee.com:xiongqb/go-utils.git
xiongqb
go-utils
go-utils
v0.0.6

搜索帮助