本节主要分享:文件读取、文件写入、线过滤器、命令行参数、命令行标识
以下代码在存放于github中如下仓库:github
Go 文件读取
程序的基本功能之一就是文件的操作,这里提供一个思路是Go 读取文件,文件读取时候需要进行错误判断。
package main
import (
"io/ioutil"
"fmt"
"os"
"bufio"
)
// 读取文件需要检查大多数的调用错误
// 这个函数帮助简化错误检查
func check(e error){
if e != nil {
panic(e)
}
}
func main(){
//最基本的文件读取到内存中
dat , err := ioutil.ReadFile("test.log")
check(err)
fmt.Print(string(dat))
//通过得到文件句柄值,可以更好的控制文件的读取。
f,err := os.Open("test.log")
check(err)
//读取到一个5字节的数组中
b1 := make([]byte,5)
n1,err:=f.Read(b1)
check(err)
fmt.Printf("%d bytes: %s\n",n1,string(b1))
//找到一个已知位置然后读取
o2 , err := f.Seek(5,0)
check(err)
b2 := make([]byte,2)
n2,err := f.Read(b2)
check(err)
fmt.Printf("%d bytes @ %d: %s\n",n2,o2,string(b2))
//没有内置的倒带,但是 Seek(0,0) 可以实现这一点
_,err = f.Seek(0,0)
check(err)
//bufio 包提供了一个缓冲的读取器,因为它具有许多小文件读取的效率,并且提供了额外的读取方式
//适当使用可以提到程序性能。
r4 := bufio.NewReader(f)
b4,err := r4.Peek(5)
check(err)
fmt.Printf("5 bytes: %s\n",string(b4))
//关闭文件
f.Close()
}
Go 文件写入实例
在Go中文件的读取和写入模式类似。写入文件同样需要检查大多数的调用错误。
package main
import (
"io/ioutil"
"os"
"fmt"
"bufio"
)
func check(e error){
if e != nil {
panic(e)
}
}
func main(){
//写入一个字符串到文件中
d1 := []byte("hello \n go \n")
err := ioutil.WriteFile("write_test.txt",d1,0644)
check(err)
//打开文件并写入数据(更为精细的调用)
f ,err := os.Create("write_test2.txt")
check(err)
//打开文件后一般操作就是立即推迟关闭文件
defer f.Close()
//按照预期的方式写入字节片段
d2 := []byte{115,111,109,101,10}
n2,err := f.Write(d2)
check(err)
fmt.Printf("Write %d bytes \n",n2)
//写入字符串
n3 , err := f.WriteString("writes \n")
fmt.Printf("write %d bytes \n",n3)
//刷新缓冲,保证数据写到硬盘中去了
f.Sync()
//bufio 提高文件读写性能
w := bufio.NewWriter(f)
n4,err:=w.WriteString("buffered\n")
fmt.Printf("write %d bytes\n",n4)
w.Flush()
}
Go 行过滤器实例
线过滤器是一种常见的程序,它读取 stdin 上的输入,处理它,然后将一些派生结果打印到 stdout 。 grep、sed是常见的线过滤器。
package main
import (
"bufio"
"os"
"strings"
"fmt"
)
func main(){
//用缓冲扫描包装无缓冲的 os.Stdin 可以让我们方便的扫描方法使扫描仪进入下一标记,
//这是默认扫描器中的下一行。
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan(){
// `Text` 返回当前标记,从输入来说这里是下一行
ucl := strings.ToUpper(scanner.Text())
//写出上面的行
fmt.Println(ucl)
}
//检查扫描期间的错误。文件结束是预期的,不会被 scan 报告为错误。
if err := scanner.Err(); err != nil {
fmt.Println(os.Stderr,"error:",err)
os.Exit(1)
}
}
Go 命令行参数实例
命令行参数是参数化程序执行的常用方法。例如 : go run hello.go 将 go 和 hello.go 作为参数应用到 go 程序中。
os.Args 提供对原始命令行参数的访问。请注意,此切片中的第一个值是程序的路径,os.Args[1:] 保存程序的参数。可以正常索引单个 arg 值。
注意:运行一下程序建议在 cmd 中进行:
go run cmd_args.go 1 2 3 4 5
package main
import (
"os"
"fmt"
)
func main(){
//os.Args 提供了原始命令行参数的访问
argsWithProg := os.Args
argsWithoutProg := os.Args[1:]
//可以单独提取参数
arg := os.Args[3]
fmt.Println(argsWithoutProg)
fmt.Println(argsWithProg)
fmt.Println(arg)
}
Go 命令行标识实例
命令行标识是制定命令行程序选项的常用方法。例如,在 go build -ldflags abc ac.go ,其中 -ldflags 是命令行标识。Go 提供了一个支持基本命令行标识解析的标识标志包。如下示例:
import (
"flag"
"fmt"
)
func main(){
//基本标志声明可用于字符串,整数和布尔选项。这里我们声明一个带有默认值
//foo 的字符串标识 word 和一个简短的描述。这个 flag.String 函数一个字符串指针
wordPtr := flag.String("word","foo","a string")
//声明 numb 和 fork标识,使用和word标识相同的方法
numbPtr := flag.Int("numb",42,"an int")
boolPtr := flag.Bool("fork",false,"a bool")
//还可以声明一个使用在程序中其他地方声明的现有变量的选项。
//我们需要传递一个指向标识声明的函数指针
var svar string
flag.StringVar(&svar,"svar","bar","a string var")
//一旦所有的标识都声明好了,就可以解析了
flag.Parse()
//显示消息
fmt.Println("word:",*wordPtr)
fmt.Println("numb:",*numbPtr)
fmt.Println("fork",*boolPtr)
fmt.Println("svar:",svar)
fmt.Println("tail",flag.Args())
}
操作输出如下:
C:\Go\MyGo\src\lesson8_file>go build cmd_flags.go
C:\Go\MyGo\src\lesson8_file>cmd_flags.exe -word=ckl -numb=05202235 -fork -svar=flag
word: ckl
numb: 1377437
fork true
svar: flag
tail []
如需进一步讨论可以加群:295023494(嵌入式)