Go笔记6-Go IO
Thu, Jun 23, 2016任何编程语言都有自己的IO系统,IO系统的接口设计是最能体现一门语言哲学的功底。而其中最具代表性的,就是文件、网络的I/O接口。
I/O
IO系统其实也可以从例子看起。首先我们看一个文件的例子。
// io.go
package main
import (
"fmt"
"os"
)
func main() {
buf := make([]byte, 1024)
f, e := os.Open("H:/ans.md") //打开文件, os.Open 返回一个实现了 io.Reader 和 io.Writer 的 *os.File;
if e != nil {
fmt.Println(e)
}
for {
fmt.Println("BEGIN")
n, _ := f.Read(buf) //一次读取 1024 字节;
if n == 0 { //到达文件末尾
fmt.Println("END")
break
}
os.Stdout.Write(buf[0:n]) //将内容写入 os.Stdout
}
defer f.Close() //确保关闭了 f;
}
我们可以从这个例子中看出,对文件的IO是非常容易的。其实文件的读写两个方法分别实现了io.Reader和io.Writer,只要类的方法原型与这两个接口的原型相同,那么你可以任意为这些对象造型为io.Reader和io.Writer,让API更加“协议”化。
有时候,我们可能会遇到较大的文件,我们可以考虑使用缓冲IO包,可以通过缓冲的方式读写文件。
如下例:
package main
import (
"fmt";
"bufio";
"os"
)
func main() {
fmt.Print("Application started")
var buf []byte = make([]byte, 1024)
f, _ := os.Open("G:\\ans.md")
defer f.Close()//保证即便发生恐慌最后也要执行关闭
//这里返回的是一个Reader指针
var r *bufio.Reader = bufio.NewReader(f)
//这里返回的是一个Writer指针
var w *bufio.Writer = bufio.NewWriter(os.Stdout)
defer w.Flush()//保证即便发生恐慌最后也要执行关闭
for {
n, _ := r.Read(buf)
if n == 0 {
break
}
w.Write(buf[:n])
}
}
如果要对一个目录操作,也是十分简单的
package main
import (
"os"
"fmt"
)
func main() {
//我们希望判断一个目录存在与否
if _, e := os.Stat("videos"); e != nil {
os.Mkdir("videos", 0777)
fmt.Println("文件夹不存在,已创建")
} else {
fmt.Println("文件夹已存在")
}
}
命令行参数
我们可以从os.Args获取切片来获取输入的命令行参数,不过这限于无参数名参数,例如
mkdir filename
。flag包提供了带参数标识的参数,例如 -file /dev/null 这种,指定命令参数名一一对应的参数。 来举一个DNS解析的小例子(不是真的解析,还是看一下命令调用的方式和解析命令参数)
package main
import (
"flag"
"fmt"
"os"
)
func main() {
dnssec := flag.Bool("dnssec", false, "Request DNSSEC Record")
port := flag.String("port", "53", "Set the query port")
flag.Usage = func() {
fmt.Fprint(os.Stdout, "Usage: %s [options] [name ...]\n", os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
if *dnssec {
fmt.Print(" dnssec :", *dnssec, "port: ", *port)
}
}
执行系统命令 os/exec包有函数可以执行外部命令,可以很简单的调用命令行命令并做其他操作。
package main
import "os/exec"
func main() {
var cmd *exec.Cmd = exec.Command("dir","/w")
cmd.Run()
}
这是个很简单的命令调用,但是没有输出,如果我们的命令调用有输出的调用的话,那么我们就需要用cmd.Output()
...
buf,err := cmd.Output() //buf是[]byte
...