go入門篇4
- 一、檔案的操作
-
- 1.1 流
- 1.2 打開關閉檔案
- 1.3 使用緩沖區讀取檔案
- 1.4 一次性讀取檔案
- 1.5 寫入檔案
- 1.6 寫的模式
- 1.7 判斷檔案是否存在
- 1.8複制檔案
- 1.9 複制圖檔
- 1.10 統計檔案中的字母和數字
- 二、指令行參數
-
- 2.1 os.Args
- 2.2 舉例
- 2.3 flag包解析指令行參數
- 三、json
-
- 3.1結構體序列化
- 3.2 map序列化
- 3.3 json.Marshal(para)
- 3.4 切片的序列化
- 3.4 基本類型的序列化
- 3.5 改變json序列化後的key
- 3.6 結構體反序列化
- 3.7 map反序列化
- 四、單元測試
-
- 4.1 簡單的案例
- 4.2 單元測試注意的點
一、檔案的操作
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