Go语言-常用工具方法

摘要

本文内容转自网络,个人学习记录使用,请勿传播

执行Clear指令清除控制台

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 清屏
func Clear() {
optSys := runtime.GOOS
if optSys == "linux" || optSys == "darwin" {
//执行clear指令清除控制台
cmd := exec.Command("clear")
cmd.Stdout = os.Stdout
err :=cmd.Run()
if err != nil {
logs.Error(err)
}
} else {
//执行clear指令清除控制台
cmd := exec.Command("cmd", "/c", "cls")
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
logs.Error(err)
}
}
}

判断指定路径是否存在、是文件还是目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 判断文件是否存在
func IsExist(fileAddr string) bool {
// 读取文件信息,判断文件是否存在
_, err := os.Stat(fileAddr)
if err != nil {
if os.IsExist(err) { // 根据错误类型进行判断
return true
}
return false
}
return true
}

// 判断目录是否存在
func IsDir(fileAddr string) bool {
s, err := os.Stat(fileAddr)
if err != nil {
return false
}
return s.IsDir()
}

// 判断文件是否存在
func IsFile(fileAddr string) bool {
s, err := os.Stat(fileAddr)
if err != nil {
return false
}
return !s.IsDir()
}

获取家目录的绝对路径

1
2
3
4
5
6
7
8
9
10
11
12
13
// 获取家目录的绝对路径
func ExpendUser(oldPath string) (realPath string) {
if oldPath == "" {
return
}
if oldPath[0:1] == "~" {
user, _ := user.Current()
realPath = path.Join(user.HomeDir, oldPath[1:])
} else {
realPath = oldPath
}
return
}

实现简单的三元运算

1
2
3
4
5
6
7
// 实现简单的三元运算
func IF(condition bool, trueVal interface{}, falseVal interface{}) interface{} {
if condition {
return trueVal
}
return falseVal
}

获取终端大小

1
2
3
4
5
6
7
8
9
10
11
12
13
w, h, err := terminal.GetSize(fd)

// 获取终端大小
func GetSttySize() (high int, width int) {
cmd := exec.Command("stty", "size")
cmd.Stdin = os.Stdin
out, _ := cmd.Output()

outList := strings.Split(strings.Replace(string(out), "\n", "", 1), " ")
high, _ = strconv.Atoi(outList[0])
width, _ = strconv.Atoi(outList[1])
return high, width
}

向上取整、向下取整、四舍五入

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"fmt"
"math"
)

func main() {
x := 1.1
fmt.Println(math.Ceil(x)) // 2
fmt.Println(math.Floor(x)) // 1
fmt.Println(int(math.Floor(x + 0/5)))
}

三个点...的用法

首先Go语言是强类型语言,当碰到无法确定传入参数数量时,可以使用...来处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

func main() {
//multiParam 可以接受可变数量的参数
multiParam("shell")
multiParam("shell", "python")
multiParam("shell", "python", "golang")
multiParam("shell", "python", "golang", "vue")
Lang := []string{"shell", "python", "golang", "vue"}
multiParam("fix", Lang...)
}
func multiParam(fixArg string, args ...string) {
//接受的参数放在args数组中
fmt.Println(fixArg)
for _, e := range args {
fmt.Println(e)
}
}

使用unixsocket交换数据 socket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// author songaimin@outlook.com 20170623
// golang 使用unixsocket交换数据
// 单元测试示例:
// package utils

// import (
// "fmt"
// u "lpaiche.com/utils"
// // "os"
// "testing"
// "time"
// )

// func TestServer(t *testing.T) {
// //声明unixsocket
// us := u.NewUnixSocket("/tmp/us.socket")
// //设置服务端接收处理
// us.SetContextHandler(func(context string) string {
// fmt.Println(context)
// now := time.Now().String() + "sssssss"
// return now
// })
// //开始服务
// go us.StartServer()
// time.Sleep(time.Second * 30)
// }

// func TestClient(t *testing.T) {
// //声明unixsocket
// us := u.NewUnixSocket("/tmp/us.socket")
// //发送数据unixsocket并返回服务端处理结果
// r := us.ClientSendContext("eeeeeee")
// fmt.Println("===============" + r)
// }

package utils

import (
"fmt"
"net"
"os"
"time"
)

type UnixSocket struct {
filename string
bufsize int
handler func(string) string
}

func NewUnixSocket(filename string, size ...int) *UnixSocket {
size1 := 10480
if size != nil {
size1 = size[0]
}
us := UnixSocket{filename: filename, bufsize: size1}
return &us
}

func (this *UnixSocket) createServer() {
os.Remove(this.filename)
addr, err := net.ResolveUnixAddr("unix", this.filename)
if err != nil {
panic("Cannot resolve unix addr: " + err.Error())
}
listener, err := net.ListenUnix("unix", addr)
defer listener.Close()
if err != nil {
panic("Cannot listen to unix domain socket: " + err.Error())
}
fmt.Println("Listening on", listener.Addr())
for {
c, err := listener.Accept()
if err != nil {
panic("Accept: " + err.Error())
}
go this.HandleServerConn(c)
}

}

//接收连接并处理
func (this *UnixSocket) HandleServerConn(c net.Conn) {
defer c.Close()
buf := make([]byte, this.bufsize)
nr, err := c.Read(buf)
if err != nil {
panic("Read: " + err.Error())
}
// 这里,你需要 parse buf 里的数据来决定返回什么给客户端
// 假设 respnoseData 是你想返回的文件内容
result := this.HandleServerContext(string(buf[0:nr]))
_, err = c.Write([]byte(result))
if err != nil {
panic("Writes failed.")
}
}

func (this *UnixSocket) SetContextHandler(f func(string) string) {
this.handler = f
}

//接收内容并返回结果
func (this *UnixSocket) HandleServerContext(context string) string {
if this.handler != nil {
return this.handler(context)
}
now := time.Now().String()
return now
}

func (this *UnixSocket) StartServer() {
this.createServer()
}

//客户端
func (this *UnixSocket) ClientSendContext(context string) string {
addr, err := net.ResolveUnixAddr("unix", this.filename)
if err != nil {
panic("Cannot resolve unix addr: " + err.Error())
}
//拔号
c, err := net.DialUnix("unix", nil, addr)
if err != nil {
panic("DialUnix failed.")
}
//写出
_, err = c.Write([]byte(context))
if err != nil {
panic("Writes failed.")
}
//读结果
buf := make([]byte, this.bufsize)
nr, err := c.Read(buf)
if err != nil {
panic("Read: " + err.Error())
}
return string(buf[0:nr])
}
————————————————
版权声明:本文为CSDN博主「可克」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/samxx8/article/details/73647910

socket服务器端和客户端简单实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// 服务端
package main

import (
"bufio"
"fmt"
"log"
"net"
)

func handleConnection(conn net.Conn) {
defer conn.Close()
data, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
fmt.Fprintf(conn, "who?\n")
data, err = bufio.NewReader(conn).ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data))
}

func main() {
l, err := net.Listen("tcp", ":2300")
if err != nil {
log.Fatal(err)
}
defer l.Close()
for {
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
go handleConnection(conn)
}
}

// 客户端
package main

import (
"bufio"
"fmt"
"log"
"net"
)

func main() {
conn, err := net.Dial("tcp", ":2300")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
fmt.Fprintf(conn, "hello\n")
res, err := bufio.NewReader(conn).ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Println(string(res))
fmt.Fprintf(conn, "Jimmy!\n")
}

flag遇到non-flag参数后无法正确解析其他参数的解决方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
"flag"
"fmt"
)

var (
Argv string
Name string
Num int
)

func init() {
flag.StringVar(&Name, "-name", "", "名字")
flag.IntVar(&Num, "-num", 0, "数量")
flag.Parse()
if len(flag.Args()) != 0 {
fmt.Println(flag.Args())
fmt.Println(flag.NArg()) // 打印non-flag的个数
Argv = flag.Args()[0]
/*
当flag遇到non-flag时会停止继续解析,将从non-flag开始的所有参数认定为non-flag
这时所有后面的参数都不能正常运行
通过源码分析可以发现flag.Parse实际是执行了flag.CommandLine.Parse方法
那我们就可以通过以下方法让其他参数继续解析
*/
flag.CommandLine.Parse(flag.Args()[1:])
}

fmt.Println(Argv)
fmt.Println(Name)
fmt.Println(Num)
}