一、文件的操作
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