Hello,各位小伙伴们,让我们继续学习Go标准库相关知识

老哥,这次把编辑器换了一下,主要是IDEA 插件不兼容,有时候莫名报红,看着难受,
换成GoLand ,专门写GO

Goland 下载地址 :https://www.jetbrains.com/go/download/#section=windows


Golang 标准库

  • os库
  • io 库
  • 其他库


os库

1、os 文件操作

package main

import (
	"fmt"
	"os"
)

//不推荐这种读,容易造成冗余
//下面有input 读取,好用
func readFile() {
	byt, _ := os.ReadFile("test2.txt")
	s := string(byt[:])
	fmt.Println(s)
}

func writeFile() {
	os.WriteFile("test2.txt", []byte("hello,Jessica"), os.ModePerm)
}

//os 操作文件
func main() {
	//1、创建文件,重复创建 会覆盖文件
	create, err := os.Create("test.txt")
	fmt.Println(create.Name(), err)

	2、创建文件目录,单级目录
	//err = os.Mkdir("t/", os.ModePerm)

	3、创建文件目录,多级目录
	//err = os.MkdirAll("a/b/c", os.ModePerm)

	//3A、删除目录或者删除文件
	//var err = os.Remove("test.txt")

	//5、删除多级目录和多级删除文件,只需要写最上面的文件目录即可
	//如 /a/b/c  --->   /a
	//err := os.RemoveAll("a/")

	//6、获取当前工作目录
	//dir, err := os.Getwd()
	//fmt.Println(dir)
	//
	7、文件重命名
	//err = os.Rename("test.txt", "test2.txt")

	//8、读文件,底层用的是File的Api
	//readFile()

	//9、写文件,底层用的是File的Api
	//writeFile()

	/*if err != nil {
		fmt.Println(err)
	}
	*/
}

2 、OS 进程相关操作

package main

import (
	"fmt"
	"os"
)

//os 进程操作
func main() {
	//1、获取当前的进程id
	currentPId := os.Getpid()
	fmt.Println(currentPId)

	//2、获取父进程的id
	ppid := os.Getppid()
	fmt.Println(ppid)

	//3、开始一个新的进程,这个没有具体写,可自行百度
	//startProcess, err := os.StartProcess("", []string(""), currentPId)

	//3A、通过进程ID查找进程
	//process, _ := os.FindProcess(1092)
	//fmt.Println(process)

	//5、等待10秒后,杀掉刚刚创建的进程
	//time.AfterFunc(time.Second*10, func() {
	//	startProcess.Kill()
	//})

	//6、等待进程
	//startProcess.wait()

	//7、获取操作系统的环境变量
	//environ := os.Environ()
	//fmt.Println(environ)

	//8、获取某个环境变量,找不到无提示
	//getEnv := os.Getenv("JAVA_HOME")
	//fmt.Println(getEnv)

	//9、获取某个环境变量,如果找不到,返回false
	//推荐使用
	//env, bool := os.LookupEnv("GO_PATH")
	//fmt.Println(env, bool)

}

io 库

3、input 读取文件内容

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {
	// 打开文件
	fp, err := os.Open("./test2.txt")
	if err != nil {
		fmt.Println("打开文件失败!", err)
		return
	}
	defer fp.Close()

	buf := make([]byte, 1024)

	for {
		// 循环读取文件
		n, err2 := fp.Read(buf)
		
		// io.EOF表示文件末尾
		if err2 == io.EOF {
			fmt.Println()
			fmt.Println("文件读取结束")
			break
		}
		fmt.Print(string(buf[:n]))
	}
}

3A、ReadBytes 同样可以实现读取文件

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

func main() {
	// 打开文件
	fp, err := os.OpenFile("./test2.txt", os.O_RDONLY, 6)
	if err != nil {
		fmt.Println("打开文件失败", err)
		return
	}
	defer fp.Close()

	// 创建文件的缓存区 
	//学过Java 的都知道,为了提高读写效率,io最好用缓冲,先把一部分数据写到缓冲区,然后等到缓存区快满了,一次性写入或者读取
	r := bufio.NewReader(fp)
	for {
		// 读取文件 (行读取) ReadBytes('\n')
		slice, err2 := r.ReadBytes('\n') // '\n'表示按行读取。 ','表示按英文逗号读取。
		fmt.Print(string(slice))         // 先打印,再判断err2 (如果文件末尾没有'\n',那么需要先打印再判断err2)
		if err2 == io.EOF {              // 如果读取到文件末尾
			break
		}
	}
}

5、ouput 写

func testIoWrite()  {
	os.WriteFile("./test2.txt", []byte("你好呀"), os.ModePerm)
}

func testWriteIo() {
	//可读可写
	file, _ := os.OpenFile("test2.txt", os.O_RDWR, os.ModePerm)

	//file 既实现了Reader接口 又实现了 Writer接口
	writer := bufio.NewWriter(file)
	_, err := writer.WriteString("hello I'm testWriteIo ... ")

	//刷一下,刷到 test2.txt
	err = writer.Flush()

	if err != nil {
		return
	}

}

6、ioutil 读 不推荐使用,同样的功能 os和io包可以做,参考链接 Go 官方文档

package main

import (
	"fmt"
	"io/ioutil"
	"os"
)

//ioutil 这个工具类已经被废弃,推荐直接使用 io os包下面的Api
func main() {
	f, _ := os.Open("./test2.txt")
	b, err := ioutil.ReadAll(f)

	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(string(b))
}

7、ioutil 写

func testWrite() {
	ioutil.WriteFile("test2.txt", []byte("hello continue Learning..."), 0664)
}

其他库

8、scan 可以分割字符串 读取

package main

import (
	"bufio"
	"fmt"
	"strings"
)

func main() {
	s := strings.NewReader("abc def g")

	bs := bufio.NewScanner(s)

	//以空格分割
	bs.Split(bufio.ScanWords)

	for bs.Scan() {
		fmt.Println(bs.Text())
	}

}

9、log

Print 打印一个红色的日志

Panic 抛出异常,终止后面的代码继续执行

Fatal (致命的;灾难性的;) 强制结束,实际上调用的是 os.exit(1) 方法

package main

import (
	"log"
)

//log 日志库

//print
func main() {
	log.Print("hello")

	//log.Panic("wo")
	
	log.Fatal("get out")
}

10、builtin

package main

import "fmt"

//builtin 内置函数

/**
append len
*/
func main() {
	//1、初始化一个切片
	s := []int{1, 2, 3}

	//2、append方法 把切片的元素添加到切片尾部,一般用于两个切片合并
	arr := append(s, 100)
	fmt.Println(arr)

	//3、初始化另外一个切片
	s1 := []int{4, 5, 6}

	//3A、两个切片合并,后面需要带3个点
	arrs := append(s, s1...)
	fmt.Println(arrs)

	//5、new 和 make 的区别
	//make 只能分配和初始化 channel slice map的数据,new 可以分配任意的数据
	//new 返回的是指针 make返回的是引用
	//new 分配的空间会被清零 make分配后,会进行初始化

}

11、errors

package main

import (
	"errors"
	"fmt"
	"time"
)

//errors
func check(s string) (string, error) {
	if s == "" {
		err := errors.New("字符串不能为空")
		return "", err
	} else {
		return s, nil
	}
}

//自定义错误
type MyError struct {
	When time.Time
	what string
}

func (e MyError) Error() string {
	return fmt.Sprintf("%v: %v", e.When, e.what)
}

func oops() error {
	return MyError{
		time.Date(1989, 3, 15, 22, 30, 0, 0, time.UTC), "the file system has gone away",
	}
}

func main() {
	//s1, err := check("")
	//
	//if err != nil {
	//	fmt.Println(err)
	//} else {
	//	fmt.Println(s1)
	//}

	//测试二
	if err := oops(); err != nil {
		fmt.Println(err)
	}

}

12、sort 排序

package main

import (
	"fmt"
	"sort"
)

//sort 排序
//适用范围:[]int、[]float64 、[]string 、自定义切片

func main() {
	s := []int{2, 4, 1, 3}
	
	//对切片排序
	sort.Ints(s)

	fmt.Println(s)

  	//判断是否已经排序过
	sorted := sort.IntsAreSorted(s)
	fmt.Println(sorted)
}

13、time

package main

import (
	"fmt"
	"time"
)

const (
	// DtFormat 这个是固定的,无法修改,它是取了GO的创建时间,作为格式化时间
	DtFormat = "2006-01-02 15:04:05"

	//DtFormat = "2006/01/02 15:04:05"
)

func testTicker() {
	ticker := time.Tick(time.Second * 1)

	for i := range ticker {
		fmt.Println(i)
	}

}

//time
func main() {
	//1、获取当前时间,同时格式化
	now := time.Now().Format(DtFormat)
	fmt.Println(now)

	//2、获取 年 月 日
	year := time.Now().Year()
	month := time.Now().Month()
	day := time.Now().Day()

	fmt.Println(year, " ", month, " ", day)

	//3、获取当前时间戳
	unix := time.Now().Unix()
	fmt.Println(unix)

	//3A、时间戳转时间
	t := time.Unix(1659516857, 0)
	fmt.Println(t)

	//5、定时器
	//testTicker()

	//6、字符串解析时间
	location, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		fmt.Println(err)
		return
	}

	timeObj, err := time.ParseInLocation(DtFormat, "2022/08/03 17:07:30", location)
	if err != nil {
		return
	}
	fmt.Println(timeObj)

}

14、json

package main

import (
	"encoding/json"
	"fmt"
)

type Person struct {
	Name  string
	Age   int
	Email string
}

// JsonToStruct
//1、结构体转json
func JsonToStruct() {
	p := Person{
		Name:  "tom",
		Age:   20,
		Email: "tom@com",
	}

	marshal, err := json.Marshal(p)
	fmt.Println(string(marshal))

	if err != nil {
		return
	}

}

// StructToJson
//2、json 转结构体
func StructToJson() {
	// ` ` 代表有多个字符串
	bytes := []byte(`{"Name":"tom","Age":20,"Email":"jessica@com"}`)
	var p2 Person
	err2 := json.Unmarshal(bytes, &p2)
	fmt.Println(p2.Name, p2.Age, p2.Email)

	if err2 != nil {
		return
	}

}

// NestJsonToMap
//嵌套类型解析到MAP
func NestJsonToMap() {
	b1 := []byte(`{"Name":"tom","Age":20,"Email":"jessica@com","friends":["jack","lucy","alis"]}`)

	//interface 在go map里面,表示任意数据类型
	var f map[string]interface{}

	err := json.Unmarshal(b1, &f)

	for k, v := range f {
		fmt.Println(k, " ", v)
	}

	if err != nil {
		return
	}

}


// FileIsExist 判断文件是否存在,通过使用os.Stat文件属性来判断
//IsNotExist err是否存在
func FileIsExist(name string) bool {
	_, err := os.Stat(name)
	if err == nil {
		return true
	} else if os.IsNotExist(err) {
		return false
	} else {
		panic(err)
	}
}

//json
func main() {
	//JsonToStruct()

	//StructToJson()

	NestJsonToMap()
}

15、json文件 解析 和 写入

新建一个json文件 test.json

{"Name":"tom","Age":20,"Email":"tom@com"}
package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Persons struct {
	Name  string
	Age   int
	Email string
}

// GetJsonTxt 记住 只要调用了 Open 或者 OpenFile,一定要记得关闭流!!!
func GetJsonTxt() {
	f, _ := os.Open("test.json")

	defer func(f *os.File) {
		err := f.Close()
		if err != nil {
		}
	}(f)
	d := json.NewDecoder(f)

	//var v1 map[string]interface{}
	//err := d.Decode(&v1)
	//fmt.Println(v1)

	var v2 Persons
	err := d.Decode(&v2)
	fmt.Println(v2)

	if err != nil {
		return
	}

}

// PutJsonTxt 将Json数据写到Json文件
func PutJsonTxt() {

	p := Persons{
		Name:  "lucy",
		Age:   21,
		Email: "lucy@com",
	}

	f, _ := os.OpenFile("test.json", os.O_WRONLY, os.ModePerm)

	defer func(f *os.File) {
		err := f.Close()
		if err != nil {
		}
	}(f)

	encode := json.NewEncoder(f)
	err := encode.Encode(p)
	if err != nil {
		return
	}

}

func main() {

	//GetJsonTxt()

	PutJsonTxt()
}

16、xml文件 解析 和 写入

新建一个xml文件 test.xml

<?xml version="1.0" encoding="UTF-8"?>
<Student>
    <name>jery</name>
    <age>23</age>
    <email>jery@com</email>
</Student>
package main

import (
	"encoding/xml"
	"fmt"
	"io/ioutil"
	"os"
)

// Student 第一个是参数名 第二个是参数类型 第三个是xml标签中的子标签名字
type Student struct {
	//学生名
	Name string `xml:"name"`

	//年龄
	Age int `xml:"age"`

	//邮箱
	Email string `xml:"email"`
}

// Students 这个用做xml写入
type Students struct {
	//文件名
	XmlName xml.Name `xml:"students"`

	Studs []Students `xml:"student"`
}

//结构体转xml
func structToXml() {
	student := Student{
		Name:  "lucy",
		Age:   22,
		Email: "lucy@com",
	}

	//这种格式没有缩进
	//marshal, _ := xml.Marshal(student)

	//这种格式有缩进,比较好看
	marshal, _ := xml.MarshalIndent(student, " ", " ")

	fmt.Println(string(marshal))
}

func getXmlTxt() {
	f, err := os.ReadFile("test.xml")

	var student Student
	err = xml.Unmarshal(f, &student)

	fmt.Println(student)

	if err != nil {
		fmt.Println(err)
	}
}

func putXmlTxt() {
	var text = `<Student></Student>`

	peo := Student{Name: "trump", Age: 75, Email: "trump@com"}

	err := xml.Unmarshal([]byte(text), &peo)

	wrb, _ := xml.MarshalIndent(peo, " ", " ")
	wrb = append([]byte(xml.Header), wrb...)

	err = ioutil.WriteFile("test.xml", wrb, os.ModePerm)
	if err != nil {
		return
	}
}

//xml
func main() {

	//structToXml()

	//getXmlTxt()

	putXmlTxt()

}

17、math

package main

import (
	"fmt"
	"math"
	"math/rand"
	"time"
)

//math
func main() {
	//1、获取π
	pi := math.Pi
	fmt.Println(pi)

	//2、获取一个绝对值
	abs := math.Abs(-3.14)
	fmt.Println(abs)

	//3、取一个数的开平方
	sqrt := math.Sqrt(64)
	fmt.Println(sqrt)

	//3A、取一个数的开立方
	cbrt := math.Cbrt(27)
	fmt.Println(cbrt)

	//5、取一个数的最大值和最小值
	max := math.Max(11, 13)
	min := math.Min(1, 3)
	fmt.Println(max, " ", min)

	//6、取一个0-100 随机数
	rand.Seed(time.Now().UnixNano())
	num := rand.Intn(100)
	fmt.Println(num)

	//7、取一个数的整数和余数
	modf, frac := math.Modf(3.69)
	fmt.Println(modf, frac)

	//8、四舍五入
	round := math.Round(4.5)
	fmt.Println(round)
}

18、最后,各位小伙伴们,麻烦给老哥一个点赞、关注、收藏三连好吗,你的支持是老哥更新最大的动力,谢谢!