go入门篇 (4)

一、文件的操作

1.1 流

  • 输入流
    数据从数据源(文件)到程序(内存)的路径
  • 输出流
    数据从程序(内存)到数据源(文件)的路径

1.2 打开关闭文件

func main(){
    
    
	file, err := os.Open("F:\\a.txt")
	if err != nil{
    
    
		fmt.Println("打开文件出错")
	}else {
    
    
		fmt.Printf("file=%v", file)
	}
	//关闭文件
	err1 :=file.Close()
	if err != nil{
    
    
		fmt.Println("关闭文件出错",err1)
	}
}

1.3 使用缓冲区读取文件

func main(){
    
    
	file, err := os.Open("F:\\a.txt")
	if err != nil{
    
    
		fmt.Println("打开文件出错")
	}
    //defer:函数要退出时,会调用后面的内容
	defer file.Close()
	reader := bufio.NewReader(file)
	for{
    
    
		//读到换行符就截至,每行都有换行符
		str, err := reader.ReadString('\n')
        if err == io.EOF{
    
    
			fmt.Println("已经读到文件的末尾了")
			break
		}
		fmt.Println(str)
	}
}

1.4 一次性读取文件

  • open和close都被封装到ReadFile中了
func main(){
    
    
	file := "f://a.txt"
	content, err := ioutil.ReadFile(file)
	if err != nil{
    
    
		fmt.Println("读取的文件出错",err)
	}
	//content是字节类型的数组
	fmt.Println(string(content))
}

1.5 写入文件

func main(){
    
    
	filename := "f://a.txt"
	file, err := os.OpenFile(filename, os.O_WRONLY | os.O_CREATE, 0666 )
    if err != nil{
    
    
		fmt.Println("打开文件出错")
		return
	}
	defer file.Close()
	str := "hello, my daday"
	writer :=bufio.NewWriter(file)
	writer.WriteString(str)
	//write是写入缓存中的,flush是写入到文件中
	writer.Flush()
	fmt.Println("写入成功")
}

1.6 写的模式

  • 删除源文件的美容
os.O_WRONLY | os.O_TRUNC
  • 在源文件内容基础上追加
os.O_WRONLY | os.O_APPEND

1.7 判断文件是否存在

func judgaFile(filePath string){
    
    
	_,err := os.Stat(filePath)
	if err == nil{
    
    
		fmt.Println("文件存在")
		return
	}
	if os.IsNotExist(err) {
    
    
		fmt.Println("文件不存在")
		return
	}
	fmt.Println("不确定文件存在不存在")

}
func main(){
    
    
	pathName := "f://a1.txt"
	judgaFile(pathName)
}

1.8复制文件

func main(){
    
    
	sourceFille := "f://a.txt"
	goalFile := "f://c.txt"
	data, err := ioutil.ReadFile(sourceFille)
    if err != nil{
    
    
		fmt.Println("读取文件出错")
		return
	}
	err1 := ioutil.WriteFile(goalFile, data, 0666)
	if err1 != nil{
    
    
		fmt.Println("读取文件出错")
	}
}

1.9 复制图片

func copyFile(resFile string, desFile string)(written64 int64, err error){
    
    
	newSrcFile, err := os.Open(resFile)
	if err != nil{
    
    
		fmt.Println("打开源文件错误")
		return
	}
	newDesFile, err :=os.OpenFile(desFile, os.O_WRONLY | os.O_CREATE, 0666)
	if err != nil{
    
    
		fmt.Println("打开目标文件错误")
		return
	}
	defer newSrcFile.Close()
	defer newDesFile.Close()
	reader := bufio.NewReader(newSrcFile)
	writer := bufio.NewWriter(newDesFile)
	return io.Copy(writer, reader)


}
func main(){
    
    
	srcFille := "f://a.jpg"
	desFille := "f://a1.jpg"
	copyFile(srcFille, desFille)

}

1.10 统计文件中的字母和数字


func main() {
    
    
	srcFille := "f://test.doc"
	var numCount int
	var wordCount int
	file, err := os.Open(srcFille)
	if err != nil {
    
    
		fmt.Println("打开文件错误")
	}
	reader := bufio.NewReader(file)
	for {
    
    
		//读到\n停止
		str, err := reader.ReadString('\n')
		if err == io.EOF {
    
    
			fmt.Println("结束")
			break
		}
		//遍历每一行的内容
		for _, value := range str {
    
    
			switch {
    
    
			case value >= 'a' && value <= 'z':
				fallthrough
			case value >= 'A' && value <= 'Z':
				wordCount++
			case value >= '0' && value <= '9':
				numCount++
			}
		}
	}
	fmt.Println(wordCount, numCount)
}

二、命令行参数

2.1 os.Args

存储命令行参数

2.2 举例

func main(){
    
    
	length := len(os.Args)
	fmt.Println(length)
	for k, v := range os.Args{
    
    
		fmt.Println(k , v)
	}
}

在这里插入图片描述

结果:
2
0 C:\Users\Administrator\AppData\Local\Temp\GoLand\___2go_build_file_go.exe
1 wqeqw:2323,sadas:2324.adas:2343

2.3 flag包解析命令行参数

func main(){
    
    
	var port int
	var name string
	flag.StringVar(&name,"u","","用户名")
	flag.IntVar(&port,"p",3306,"端口号")
	flag.Parse()
	fmt.Println(name, port)
}

在这里插入图片描述

结果:
ybx 2344

三、json

3.1结构体序列化

  • 结构体属性名如果第一个字母小写,则不会被序列化,大写才会被序列化
type Student struct {
    
    
	//注意:如果属性小写,则序列化不了,序列化的结果就是空
	name string
	Age int
	Address string
	Hobby []string
}
func main(){
    
    
	var stu Student = Student{
    
    
		name:"jack",
		Age:23,
		Address:"西安",
		Hobby:[]string{
    
    
			"basketball","football","ping-pong","eat",
		},
	}
	res, err := json.Marshal(&stu)
	if err != nil{
    
    
		fmt.Println("序列化失败")
		return
	}
	fmt.Println(string(res))
}

3.2 map序列化

type Student struct {
    
    
	//注意:如果属性小写,则序列化不了,序列化的结果就是空
	name string
	Age int
	Address string
	Hobby []string
}
func main(){
    
    
	var stu Student = Student{
    
    
		name:"jack",
		Age:23,
		Address:"西安",
		Hobby:[]string{
    
    
			"basketball","football","ping-pong","eat",
		},
	}
	var mymap map[string]interface{
    
    } = make(map[string]interface{
    
    })
	mymap["name"] = "jack"
	mymap["age"] = 36
	mymap["stu"] = stu
	res, err := json.Marshal(mymap)
	if err != nil{
    
    
		fmt.Println("序列化失败")
		return
	}
	fmt.Println(string(res))
}

3.3 json.Marshal(para)

注意para是引用类型

3.4 切片的序列化

type Student struct {
    
    
	//注意:如果属性小写,则序列化不了,序列化的结果就是空
	name string
	Age int
	Address string
	Hobby []string
}
func main(){
    
    
	var stu Student = Student{
    
    
		name:"jack",
		Age:23,
		Address:"西安",
		Hobby:[]string{
    
    
			"basketball","football","ping-pong","eat",
		},
	}
	var mymap []map[string]interface{
    
    }
	var mymap1 map[string]interface{
    
    } = make(map[string]interface{
    
    })
	var mymap2 map[string]interface{
    
    } = make(map[string]interface{
    
    })
	mymap1["name"] = "jack"
	mymap1["age"] = 36
	mymap1["stu"] = stu
	mymap2["name"] = "jack"
	mymap2["age"] = 36
	mymap2["stu"] = stu
	mymap = append(mymap, mymap2)
	mymap = append(mymap,mymap1)
	res, err := json.Marshal(mymap)
	if err != nil{
    
    
		fmt.Println("序列化失败")
		return
	}
	fmt.Println(string(res))
}

3.4 基本类型的序列化

  • 基本类型的序列化没有什么意义
func main() {
    
    
	var num int = 23
	res, err := json.Marshal(num)
	if err != nil{
    
    
		fmt.Println("序列化出错")
	}
	fmt.Println(string(res))
}

3.5 改变json序列化后的key

type Student struct {
    
    
	//注意:如果属性小写,则序列化不了,序列化的结果就是空
	name string`json:"stu_name"`
	Age int	`json:"stu_age"`
	Address string`json:"stu_address"`
	Hobby []string
}

3.6 结构体反序列化

func main(){
    
    
    str := "{\"stu_age\":23,\"stu_address\":\"西安\",\"Hobby\":[\"basketball\",\"football\",\"ping-pong\",\"eat\"]}"
	var stu1 Student
	err1 := json.Unmarshal([]byte(str), &stu1)
	if err1!= nil{
    
    
		fmt.Println("反序列化出错")
	}
	fmt.Println(stu1.name,stu1.Age, stu1.Hobby,stu1.Address)
}

3.7 map反序列化

  • map反序列化会自动make,不需要自己make
func main(){
    
    
	var stu Student = Student{
    
    
		name:"jack",
		Age:23,
		Address:"西安",
		Hobby:[]string{
    
    
			"basketball","football","ping-pong","eat",
		},
	}
	var mymap map[string]interface{
    
    } = make(map[string]interface{
    
    })
	mymap["name"] = "ybx"
	mymap["age"] = 12
	mymap["stu"] = stu
	res, err := json.Marshal(mymap)
	if err != nil{
    
    
		fmt.Println("序列化失败")
		return
	}
	var mymap2 map[string]interface{
    
    }
	err1 := json.Unmarshal(res, &mymap2)
	if err1!= nil{
    
    
		fmt.Println("反序列化出错")
	}
	fmt.Println(mymap2)
}

四、单元测试

4.1 简单的案例

package test

import "testing"

//注意测试函数严格符合一定的命名规范
func TestCal(t *testing.T){
    
    
	//调用被测试的函数
	res := cal()
	if res != 45{
    
    
		t.Fatal("测试结果与期望结果不符")
	}
	t.Logf("执行结果正确")
}
结果:
=== RUN   TestCal
45
    cal_test.go:12: 执行结果正确
--- PASS: TestCal (0.00s)
PASS

4.2 单元测试注意的点

  • 测试函数的命名时:Test+函数名大写,也可以是其他的名称,但是名称首字母必须大写
  • 测试文件的命名是:被测试的文件名+_test

猜你喜欢

转载自blog.csdn.net/qq_42306803/article/details/120247863