1、终端读写
操作终端相关
文件句柄常量
os.Stdin:标准输入
os.Stdout:标准输出
os.Stderr:标准错误输出
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.Println("From the string we read: ", f, i, s) //可以打印出变量 fmt.Printf("Hi %s %s! ", firstName, lastName) //只可以打印出格式化的字符串,字符串类型的变量,不可以输出整型变量和整型 fmt.Scan(&firstName, &lastName) //输入的参数按空格分开 fmt.Scanln(&firstName, &lastName) //Scanln和Scan非常类似,只是Scanln只会接受一个回车,收到回车就扫描结束了 fmt.Scanf("%s , %s", &firstName, &lastName) /* 1、Scanf中间有一个逗号,但逗号和%s间有空格,因为Scanf是用空格来区分不同的参数的。 2、输入的参数firstName , lastName格式与Scanf中指定的fmt要一致。 3、中间的逗号,Scanf会自动格式匹配不会添加到变量中 */ fmt.Sscanf(input, format, &f, &i, &s) }
bufio带缓冲区的读写
package main import ( "bufio" "fmt" "os" ) func main() { reader := bufio.NewReader(os.Stdin) //从终端接收输入的信息 line, err := reader.ReadString(' ') //双引号是字符串,单引号是字符,读取一行结束 if err != nil { fmt.Println("read error:", err) return } }
package main import ( "bufio" "fmt" "math/rand" "time" ) type RandStr struct { } func (r *RandStr) Read(p []byte) (n int, err error) { fmt.Printf("Len(p)=%d ", len(p)) source := "abcdefghijk0123456789" for i := 0; i < 32; i++ { index := rand.Intn(len(source)) p[i] = source[index] //P的长度已经分配好了,不能使用append方法,会越界 } p[32] = ' ' return len(p), nil } func main() { rand.Seed(time.Now().UnixNano()) //修改随机数种子 var randStr = &RandStr{} randReader := bufio.NewReader(randStr) //自己实现Read接口 lineByte, prefix, _ := randReader.ReadLine() fmt.Printf("rand:%s prefix:%v ", string(lineByte), prefix) }
练习:从终端读取一行字符串,统计英文、数字、空格以及其他字符的数量。
package main import ( "os" "bufio" "fmt" ) func stat(str string) { var en_count int var sp_count int var num_count int var other_count int utf8Arr := []rune(str) for _, v := range utf8Arr { if v >= 'a' && v <= 'z' || v >= 'A' && v <= 'Z' { en_count++ continue } if v == ' ' { sp_count++ continue } if v >= '0' && v<= '9' { num_count++ continue } other_count++ } fmt.Printf("en=%d sp=%d num=%d other=%d ", en_count, sp_count, num_count, other_count) } func main(){ reader := bufio.NewReader(os.Stdin) line, err := reader.ReadString(' ') if err != nil { fmt.Printf("read string failed, err:%v ", err) return } stat(line) }
文本文件读写
1、os.File封装所有文件相关操作,之前讲的 os.Stdin,os.Stdout, os.Stderr都是 *os.File
( 程序启动自动打开句柄os.Stdin,os.Stdout, os.Stderr,内部都实现了Read方法,os.File内部也实现了Read方法)
a、打开一个文件进行读操作: os.Open(name string) (*File, error)
b、关闭 一个 文件:File.Close()
package main import ( "os" "fmt" "io" ) func testFile() { // 文件没有一行一行读取的功能 file, err := os.Open("D:/运维人员如何最大限度避免误删除文件-演示文件.txt") if err != nil { fmt.Println("open file failed:", err) return } defer file.Close() //关闭文件句柄 var data [1024]byte //传一个数据进file文件句柄 for { //循环读取 n, err := file.Read(data[:]) //n为读取的有效字节 if err == io.EOF { //读到文件末尾 break } if err != nil { //错误信息 fmt.Printf("read file error:%s ", err) return } str := string(data[0:n]) fmt.Println(str) } } func main(){ testFile() }
package main
import (
"os"
"fmt"
"io"
"bufio"
)
func testBufIO() {
//文件如果要一行一行读取,可以用bufio读取
file, err := os.Open("D:/运维人员如何最大限度避免误删除文件-演示文件.txt")
if err != nil {
fmt.Println("open file failed:", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString('
') //一行一行读取
if err == io.EOF {
break
}
if err != nil {
fmt.Printf("read file error:%s
", err)
return
}
fmt.Println(line)
}
}
func main(){
testBufIO()
}
package main import ( "os" "fmt" "io/ioutil" ) func testIoUtil() { //一次读取一个文件 data, err := ioutil.ReadFile("D:/运维人员如何最大限度避免误删除文件-演示文件.txt") //ReadFile方法内部自己打开文件 //Readall传一个实现了Read方法的接口进去 if err != nil { fmt.Printf("read file failed:%v ", err) return } fmt.Printf("%s ", string(data)) } func main(){ testIoUtil() }
读取压缩文件
package main import ( "io" "bufio" "compress/gzip" //导入相应的压缩格式 "fmt" "os" ) func main(){ file, err := os.Open("D:/张导讲命令.txt.gz") if err != nil { fmt.Println("open file failed:", err) return } defer file.Close() reader, err := gzip.NewReader(file) //解压文件句柄reader只能整体读取,不能按行读取 if err != nil { fmt.Printf("gzip failed, err:%v ", err) return } bufReader := bufio.NewReader(reader) //bufio可以按行读取 for { line, err := bufReader.ReadString(' ') if err != nil { if err == io.EOF { break } fmt.Printf("read failed, err:%v ", err) return } fmt.Printf("%s", line) } }
文件写入
os.OpenFile(“output.dat”, os.O_WRONLY|os.O_CREATE, 0666)
第二个参数: 打开文件模式: 第三个参数:权限控制:
1. os.O_WRONLY:只写 r ——> 0004
2. os.O_CREATE:创建文件 w——> 0002
3. os.O_RDONLY:只读 x——> 0001
4. os.O_RDWR:读写
5. os.O_TRUNC :清空
package main import ( "os" "fmt" ) func testWriteFile() { file , err := os.OpenFile("D:/mylog.txt", os.O_WRONLY|os.O_CREATE, 0666) if err != nil { fmt.Printf("open file failed:%v ", err) return } defer file.Close() for i := 0; i < 10; i++{ file.WriteString(fmt.Sprintf("hello %d ", i)) } } func main() { testWriteFile() }
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 ") return } defer outputFile.Close() outputWriter := bufio.NewWriter(outputFile) //bufio写入,速度较快 outputString := "hello world! " for i := 0; i < 10; i++ { outputWriter.WriteString(outputString) } outputWriter.Flush() }
拷贝文件
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) //文件拷贝 }
命令行参数
os.Args是 一个string的切片, 用来存储所有的命令行参数
package main import ( "os" "fmt" ) func main(){ for index, val := range os.Args{ //第一参数永远是可执行文件 fmt.Printf("args[%d] = %s ",index,val) } }
flag包的使用,用来解析命令行参数:
flag.BoolVar(&test, "b", false, "print on newline")
flag.StringVar(&str, "s", "", "print on newline")
flag.IntVar(&count, "c", 1001, "print on newline")
package main import ( //"os" "fmt" "flag" ) var ( conf string level int ) func init(){ flag.StringVar(&conf, "c", "D:/etc/test.conf", "请指定配置文件路径") //第三个参数是默认值,第四个参数是参数说明 flag.IntVar(&level, "l", 8, "请指定日志级别") flag.Parse() //要解析才生效 } func main(){ fmt.Printf("conf is:%s ", conf) fmt.Printf("level is:%d ", level) } //在命令行输入cmd_test.exe -c "etc/test.conf" l 10
package main import ( "bufio" "flag" "fmt" "io" "os" ) func cat(r *bufio.Reader) { for { buf, err := r.ReadBytes(' ') if err == io.EOF { break } fmt.Fprintf(os.Stdout, "%s", buf) //文件读取输出到终端 } } 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 ",os.Args[0], flag.Arg(i), err.Error()) continue } cat(bufio.NewReader(f)) } }
package main import ( "os" "fmt" "io" ) func cat (filename string) { file, err := os.Open(filename) if err != nil { fmt.Printf("open %s failed, err:%v ", filename, err) return } defer file.Close() io.Copy(os.Stdout, file) //将文件的内容输出到终端,以io.Copy方式实现 } func main() { if (len(os.Args) == 1) { fmt.Println("请指定文件名") return } for i := 1; i <len(os.Args);i++{ cat(os.Args[i]) } }
package main import ( "bufio" "fmt" "os" ) func main() { fmt.Fprintf(os.Stdout, "%s ", "hello world! - unbuffered") buf := bufio.NewWriter(os.Stdout) fmt.Fprintf(buf, "%s ", "hello world! - buffered") buf.Flush() }
Json数据协议
1.导 入包:Import “encoding/json”
2.序列列化: json.Marshal(data interface{})
3.反序列列化: json.UnMarshal(data []byte, v interface{})
package main import ( "encoding/json" "fmt" "math/rand" "os" ) type Student struct { Name string `json:"name"` //定义json串里面的key Age int `json:"age"` Score float32 `json:"score"` } func testWriteFile(){ var stus []*Student for i := 0; i <1000; i++{ stu := &Student { Name:fmt.Sprintf("stu%d", i), Age:rand.Intn(100), Score:rand.Float32()*100, } stus = append(stus, stu) } data, err := json.Marshal(stus) //序列化,可以传任何数据类型进去,因为是空接口 if err != nil { fmt.Printf("json failed, err:%v ", err) return } file, err := os.OpenFile("d:/stu.dat", os.O_CREATE|os.O_WRONLY, 0666) //打开文件 if err != nil { fmt.Printf("file failed, err:%v ", err) return } defer file.Close() n, err := file.Write(data) //将json字符串写入文件 if err != nil { fmt.Printf("write failed, err:%v ", err) return } fmt.Printf("write %d succ ", n) } func main(){ testWriteFile() }
package main import ( "encoding/json" "fmt" "os" "io/ioutil" ) type Student struct { Name string `json:"name"` //定义json串里面的key Age int `json:"age"` Score float32 `json:"score"` } func testReadFile(){ file, err := os.OpenFile("d:/stu.dat", os.O_RDONLY, 0666) if err != nil { fmt.Printf("file failed, err:%v ", err) return } defer file.Close() data, err := ioutil.ReadAll(file) if err != nil { fmt.Printf("read all failed, err:%v ", err) } var stus []*Student err = json.Unmarshal(data, &stus) //反序列化 if err != nil { fmt.Printf("json unmarshal failed, err:%v ", err) return } fmt.Printf("total student:%d ", len(stus)) for i := 0; i <10; i++{ fmt.Printf("student:%#v ", stus[i]) } } func main(){ testReadFile() }
错误处理
定义错误
package main import ( "errors" "fmt" ) var errNotFound error = errors.New("Not found error") func main() { fmt.Printf("error: %v", errNotFound) }
Panic&Recover
package main import ( "fmt" "time" ) func set(p *int) { *p = 123 //空指针赋值挂掉 } func test() { defer func() { err := recover() if err != nil { fmt.Printf("panic:%v ", err) //捕获异常,不让程序挂掉 } }() var p *int set(p) fmt.Printf("*p=%d ", *p) } func main() { for { test() time.Sleep(time.Second) } }