Go语言系列- 读写操作
终端读写
1. 终端读写
操作终端相关文件句柄常量
- os.Stdin:标准输入
- os.Stdout:标准输出
- os.Stderr:标准错误输出
2. 终端读写示例
package main import ( "fmt" ) var ( firstName, lastName, s string i int f float32 input = "56.12 / 5212 / Go" format = "%f / %d / %s" ) func main() { fmt.Println("Please enter your full name: ") fmt.Scanln(&firstName, &lastName) // fmt.Scanf("%s %s", &firstName, &lastName) fmt.Printf("Hi %s %s!\n", firstName, lastName) // Hi Chris Naegels fmt.Sscanf(input, format, &f, &i, &s) fmt.Println("From the string we read: ", f, i, s) }
package main import "fmt" type student struct { Name string Age int Score float32 } func main() { var str = "stu01 18 89.92" var stu student fmt.Sscanf(str, "%s %d %f", &stu.Name, &stu.Age, &stu.Score) fmt.Println(stu) }
3. 带缓冲区的读写
package main import ( "bufio" "fmt" "os" ) var inputReader *bufio.Reader var input string var err error func main() { inputReader = bufio.NewReader(os.Stdin) fmt.Println("Please enter some input: ") input, err = inputReader.ReadString('\n') if err == nil { fmt.Printf("The input was: %s\n", input) } }
package main import ( "bufio" "fmt" "os" ) func main() { reader := bufio.NewReader(os.Stdin) str, err := reader.ReadString('\n') if err != nil { fmt.Println("read string failed, err:", err) return } fmt.Printf("read str success, ret: %s\n", str) } // go run go_dev/day7/example/example3/main
文件读写
1. os.File封装所有文件相关操作,之前讲的 os.Stdin,os.Stdout, os.Stderr都是*os.File
- 打开一个文件进行读操作: os.Open(name string) (*File, error)
- 关闭一个文件:File.Close()
2. 文件操作示例
package main import ( "bufio" "fmt" "os" ) func file_write() { // 文件读写 file, err := os.OpenFile("test.log", os.O_CREATE|os.O_WRONLY, 0664) if err != nil { fmt.Println("open file err,:", err) return } fmt.Fprintf(file, "do balance error\n") file.Close() } func main() { // file_write() file, err := os.Open("test.log") if err != nil { fmt.Println("read file failed, err:", err) return } defer file.Close() reader := bufio.NewReader(file) str, err := reader.ReadString('\n') if err != nil { fmt.Println("read string failed, err:", err) return } fmt.Printf("read str success, ret: %s\n", str) }
3. 读取整个文件示例
package main import ( "fmt" "io/ioutil" "os" ) func main() { inputFile := "products.txt" outputFile := "products_copy.txt" buf, err := ioutil.ReadFile(inputFile) if err != nil { fmt.Fprintf(os.Stderr, "File Error: %s\n", err) return } fmt.Printf("%s\n", string(buf)) err = ioutil.WriteFile(outputFile, buf, 0x644) if err != nil { panic(err.Error()) } }
4. 读取压缩文件示例
package main import ( "bufio" "compress/gzip" "fmt" "os" ) func main() { fName := "MyFile.gz" var r *bufio.Reader fi, err := os.Open(fName) if err != nil { fmt.Fprintf(os.Stderr, "%v, Can’t open %s: error: %s\n", os.Args[0], fName, err) os.Exit(1) } fz, err := gzip.NewReader(fi) if err != nil { fmt.Fprintf(os.Stderr, "open gzip failed, err: %v\n", err) return } r = bufio.NewReader(fz) for { line, err := r.ReadString('\n') if err != nil { fmt.Println("Done reading file") os.Exit(0) } fmt.Println(line) } }
5. 文件写入
os.OpenFile(“output.dat”, os.O_WRONLY|os.O_CREATE, 0666)
第二个参数:文件打开模式
- 1. os.O_WRONLY:只写
- 2. os.O_CREATE:创建文件
- 3. os.O_RDONLY:只读
- 4. os.O_RDWR:读写
- 5. os.O_TRUNC :清空
第三个参数:权限控制:
- r --> 004w --> 002x --> 001
6.文件写入示例
package main import ( "bufio" "fmt" "os" ) func main() { outputFile, outputError := os.OpenFile("output.dat", os.O_WRONLY|os.O_CREATE, 0666) if outputError != nil { fmt.Printf("An error occurred with file creation\n") return } defer outputFile.Close() outputWriter := bufio.NewWriter(outputFile) outputString := "hello world!\n" for i := 0; i < 10; i++ { outputWriter.WriteString(outputString) } outputWriter.Flush() }
7. 拷贝文件
package main import ( "fmt" "io" "os" ) func main() { CopyFile("target.txt", "source.txt") fmt.Println("Copy done!") } func CopyFile(dstName, srcName string) (written int64, err error) { src, err := os.Open(srcName) if err != nil { return } defer src.Close() dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return } defer dst.Close() return io.Copy(dst, src) }
8 读取文件,统计英文、数字、空格以及其他字符的数量。
package main import ( "bufio" "fmt" "io" "os" ) type CharCount struct { ChCount int NumCount int SpaceCount int OtherCount int } func main() { file, err := os.Open("test.log") if err != nil { fmt.Println("read file failed, err:", err) return } defer file.Close() var count CharCount reader := bufio.NewReader(file) for { str, err := reader.ReadString('\n') if err == io.EOF { break } if err != nil { fmt.Printf("read file failed, err%s", err) break } runeArr := []rune(str) for _, v := range runeArr { switch { case v >= 'a' && v <= 'z': fallthrough case v >= 'A' && v <= 'Z': count.ChCount++ case v == ' ' || v == '\t': count.SpaceCount++ case v >= '0' && v <= '9': count.NumCount++ default: count.OtherCount++ } } } fmt.Printf("char count: %d\n", count.ChCount) fmt.Printf("num count: %d\n", count.NumCount) fmt.Printf("space count: %d\n", count.SpaceCount) fmt.Printf("other count: %d\n", count.OtherCount) }
9. 带缓冲区的文件读写
package main import ( "bufio" "flag" "fmt" "io" "os" ) func cat(r *bufio.Reader) { for { buf, err := r.ReadBytes('\n') if err == io.EOF { break } fmt.Fprintf(os.Stdout, "%s", buf) return } } func main() { flag.Parse() if flag.NArg() == 0 { cat(bufio.NewReader(os.Stdin)) } for i := 0; i < flag.NArg(); i++ { f, err := os.Open(flag.Arg(i)) if err != nil { fmt.Fprintf(os.Stderr, "%s:error reading from %s: %s\n", os.Args[0], flag.Arg(i), err.Error()) } continue } cat(bufio.NewReader(f)) }
10. 带缓冲区的终端读写
package main import ( "bufio" "fmt" "os" ) func main() { fmt.Fprintf(os.Stdout, "%s\n", "hello world! - unbuffered") buf := bufio.NewWriter(os.Stdout) fmt.Fprintf(buf, "%s\n", "hello world! - buffered") buf.Flush() }
命令行参数
os.Args是一个string的切片,用来存储所有的命令行参数
1. flag包的使用,用来解析命令行参数:
- flag.BoolVar(&test, "b", false, "print on newline")
- flag.StringVar(&str, "s", "", "print on newline")
- flag.IntVar(&count, "c", 1001, "print on newline")
2. 命令行参数解析
package main import ( "flag" // command line option parser "fmt" ) func main() { var test bool var str string var count int flag.BoolVar(&test, "b", false, "print on newline") flag.StringVar(&str, "s", "", "print on newline") flag.IntVar(&count, "c", 1001, "print on newline") flag.Parse() fmt.Println(test) fmt.Println(str) fmt.Println(count) }
3. 示例
package main import ( "fmt" "os" ) func main() { fmt.Printf("len of args:%d\n", len(os.Args)) for i, v := range os.Args { fmt.Printf("args[%d]: %s\n", i, v) } }
package main import ( "flag" "fmt" ) func main() { var confPath string var logLevel int flag.StringVar(&confPath, "c", "", "please input conf Path") flag.IntVar(&logLevel, "d", 10, "please input log level") flag.Parse() fmt.Println("path:", confPath) fmt.Println("log level:", logLevel) } // go run go_dev/day7/example/example7/main -c d:/python -d 1
Json数据协议
- 1. 导入包:Import “encoding/json”
- 2. 序列化: json.Marshal(data interface{})
- 3. 反序列化: json.UnMarshal(data []byte, v interface{})
json序列化结构体,map,slice和int
package main import ( "encoding/json" "fmt" ) type User struct { UserName string `json:"username"` Nickname string `json:"nickname"` Age int Birthday string Sex string Email string Phone string } func testStruct() { user1 := &User{ UserName: "user1", Nickname: "超级英雄", Age: 18, Birthday: "2008/8/8", Sex: "男", Email: "mayun@qq.com", Phone: "110", } data, err := json.Marshal(user1) if err != nil { fmt.Println("json.marsha1 failed, err:", err) return } fmt.Printf("%s\n", string(data)) } func testInt() { var age = 100 data, err := json.Marshal(age) if err != nil { fmt.Println("json.marsha1 failed, err:", err) return } fmt.Printf("%s\n", string(data)) } func testMap() { var m map[string]interface{} m = make(map[string]interface{}) m["username"] = "user1" m["age"] = 18 m["sex"] = "女" data, err := json.Marshal(m) if err != nil { fmt.Println("json.marsha1 failed, err:", err) return } fmt.Printf("%s\n", string(data)) } func testSlice() { var m map[string]interface{} var s []map[string]interface{} m = make(map[string]interface{}) m["username"] = "user1" m["age"] = 18 m["sex"] = "女" s = append(s, m) data, err := json.Marshal(s) if err != nil { fmt.Println("json.marsha1 failed, err:", err) return } fmt.Printf("%s\n", string(data)) } func main() { testStruct() testInt() testMap() testSlice() }
json序列化示例
package main import ( "encoding/json" "fmt" ) type User struct { UserName string `json:"username"` Nickname string `json:"nickname"` Age int Birthday string Sex string Email string Phone string } func testStruct() (ret string, err error) { user1 := &User{ UserName: "user1", Nickname: "超级英雄", Age: 18, Birthday: "2008/8/8", Sex: "男", Email: "mayun@qq.com", Phone: "110", } data, err := json.Marshal(user1) if err != nil { fmt.Println("json.marsha1 failed, err:", err) return } ret = string(data) return } func testMap() (ret string, err error) { var m map[string]interface{} m = make(map[string]interface{}) m["username"] = "user1" m["age"] = 18 m["sex"] = "女" data, err := json.Marshal(m) if err != nil { fmt.Println("json.marsha1 failed, err:", err) return } ret = string(data) return } func test() { data, err := testStruct() if err != nil { fmt.Println("test struct failed, err:", err) return } var user1 User err = json.Unmarshal([]byte(data), &user1) if err != nil { fmt.Println("unmarshal failed", err) return } fmt.Println(user1) } func test2() { data, err := testMap() if err != nil { fmt.Println("test map failed, err:", err) return } var m map[string]interface{} err = json.Unmarshal([]byte(data), &m) if err != nil { fmt.Println("unmarshal failed", err) return } fmt.Println(m) } func main() { test() test2() }
定义错误
package main import ( "errors" "fmt" ) var errNotFound error = errors.New("Not found error") func main() { fmt.Printf("error: %v", errNotFound) }
自定义错误
type error interface { Error() string }
package main import ( // "fmt" ) type PathError struct { Op string Path string err string } func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() } func test() error { return &PathError{ Op: "op", Path: "path", } } func main() { test() }
判断自定义错误
switch err := err.(type) { case ParseError: PrintParseError(err) case PathError: PrintPathError(err) ... default: }
示例
package main import ( "fmt" "os" "time" ) type PathError struct { path string op string createTime string message string } func (p *PathError) Error() string { return fmt.Sprintf("path=%s op=%s createTime=%s message=%s", p.path, p.op, p.createTime, p.message) } func Open(filename string) error { file, err := os.Open(filename) if err != nil { return &PathError{ path: filename, op: "read", message: err.Error(), createTime: fmt.Sprintf("%v", time.Now()), } } defer file.Close() return nil } func main() { err := Open("c:/sasassas.txt") switch v := err.(type) { case *PathError: fmt.Println("get path error,", v) default: } }
Panic&Recove
panic的作用就是抛出一条错误信息,从它的参数类型可以看到它可以抛出任意类型的错误信息。在函数执行过程中的某处调用了panic,则立即抛出一个错误信息,同时函数的正常执行流程终止,但是该函数中panic之前定义的defer语句将被依次执行。之后该goroutine立即停止执行。
recover()用于将panic的信息捕捉。recover必须定义在panic之前的defer语句中。在这种情况下,当panic被触发时,该goroutine不会简单的终止,而是会执行在它之前定义的defer语句。
package main import ( "fmt" ) func badCall() { panic("bad end") } func test() { defer func() { if e := recover(); e != nil { fmt.Printf("Panicking %s\r\n", e) } }() badCall() fmt.Printf("After bad call\r\n") } func main() { fmt.Printf("Calling test\r\n") test() fmt.Printf("Test completed\r\n") }