Golang IO 操作
Posted 知其黑、受其白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang IO 操作相关的知识,希望对你有一定的参考价值。
阅读目录
- 1 格式化输入
- 2 格式化输入背后的原理
- 3 bufio 包的使用
- 4 命令行参数处理和 urfave/cli 使用
- 5 实现一个简易的计算器
- 6 文件打开和读写
- 7 读取压缩文件
- 8 文件写入
- 9 bufio原理和cat命令实现
- defer 详解
- 实现一个类似Linux的tree命令
1 格式化输入
从终端获取用户输入
格式化输入,空格作为分隔符,占位符和格式化输出一致。
fmt.Scanf(format string,a...interface)
从终端获取用户输入,存储在Scanln中的参数里,空格和换行符作为分隔符。
fmt.Scan(a...interface)
从终端获取用户输入,存储在Scanln中的参数里,空格作为分隔符,遇到换行符结束。
fmt.Scanln(a...interface)
fmt.Scanf
package main
import "fmt"
func testInput()
var a int
var b string
var c float32
fmt.Scanf("%d%s%f", &a, &b, &c)
fmt.Printf("a=%d b=%s c=%f\\n", a, b, c)
func main()
testInput()
PS E:\\TEXT\\test_go\\one> go run .\\main.go
33 wgchen 888888.88
a=33 b=wgchen c=888888.875000
PS E:\\TEXT\\test_go\\one>
Windows 终端输入第一个回车结束,只能获取到第一个。
fmt.Scanf("%d",&a)
fmt.Scanf("%s",&a)
fmt.Scanf("%f",&a)
\\n
的意思是直到遇到换行符为止。
fmt.Scanf("%d\\n",&a)
fmt.Scanf("%s\\n",&a)
fmt.Scanf("%f\\n",&a)
fmt.Scan
package main
import "fmt"
func testScan()
var a int
var b string
var c float32
fmt.Scan(&a, &b, &c)
fmt.Printf("a=%d b=%s c=%f\\n", a, b, c)
func main()
testScan()
PS E:\\TEXT\\test_go\\one> go run .\\main.go
12
cc
888888.88
a=12 b=cc c=888888.875000
PS E:\\TEXT\\test_go\\one>
fmt.Scanln
package main
import "fmt"
func testScanln()
var a int
var b string
var c float32
fmt.Scanln(&a, &b, &c)
fmt.Printf("a=%d b=%s c=%f\\n", a, b, c)
func main()
testScanln()
PS E:\\TEXT\\test_go\\one> go run .\\main.go
88
a=88 b= c=0.000000
PS E:\\TEXT\\test_go\\one> go run .\\main.go
88 hello 888.888
a=88 b=hello c=888.888000
PS E:\\TEXT\\test_go\\one>
2 格式化输入背后的原理
os.Stdin.Read 终端读取
package main
import (
"fmt"
"os"
)
func main()
var buf [16]byte
os.Stdin.Read(buf[:])
fmt.Println(string(buf[:]))
os.Stdout.WriteString 终端输出
package main
import (
"os"
)
func main()
var buf [16]byte
os.Stdin.Read(buf[:])
// fmt.Println(string(buf[:]))
os.Stdout.WriteString(string(buf[:]))
PS E:\\TEXT\\test_go\\one> go run .\\main.go
this is hahahahah
this is hahahaha
PS E:\\TEXT\\test_go\\one>
fmt.Fscanf 文件格式输入
package main
import (
"fmt"
"os"
)
func main()
var a int
var b string
var c float32
fmt.Fscanf(os.Stdin, "%d%s%f", &a, &b, &c)
// fmt.Scanf("%d%s%f", &a, &b, &c)
fmt.Println(a, b, c)
PS E:\\TEXT\\test_go\\one> go run .\\main.go
1 a 3.3
PS E:\\TEXT\\test_go\\one> go run .\\main.go
1 a 3.3
1 a 3.3
PS E:\\TEXT\\test_go\\one>
fmt.Fprintln 格式化输出到文件中
package main
import (
"fmt"
"os"
)
func main()
var a int
var b string
var c float32
fmt.Fscanf(os.Stdin, "%d%s%f", &a, &b, &c)
fmt.Fprintln(os.Stdout, a, b, c)
PS E:\\TEXT\\test_go\\one> go run .\\main.go
66 aa 33.33
66 aa 33.33
PS E:\\TEXT\\test_go\\one>
3 bufio 包的使用
带缓冲区的文件读写。
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)
PS E:\\TEXT\\test_go\\one> go run .\\main.go
Please enter some input:
wgchen
The input was:wgchen
PS E:\\TEXT\\test_go\\one>
4 命令行参数处理和 urfave/cli 使用
os.Args 命令行参数的切片。
package main
import (
"fmt"
"os"
)
func main()
// who := "Alice"
// if len(os.Args) > 1
// who += strings.Join(os.Args[1:], " ")
//
// fmt.Println("Good Morning", who)
fmt.Println("args[0]=", os.Args[0])
if len(os.Args) > 1
for index, v := range os.Args
if index == 0
continue
fmt.Printf("args[%d]=%v\\n", index, v)
PS E:\\TEXT\\test_go\\one> go run .\\main.go first secnd
args[0]= C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build893513147\\b001\\exe\\main.exe
args[1]=first
args[2]=secnd
PS E:\\TEXT\\test_go\\one>
命令行参数处理
flag 包命令行选项的使用。
package main
import (
"flag"
"fmt"
)
var recusive bool
var test string
var level int
func init()
flag.BoolVar(&recusive, "r", false, "recusive xxx")
flag.StringVar(&test, "t", "default string", "string option")
flag.IntVar(&level, "l", 1, "level of xxxxx")
flag.Parse()
func main()
fmt.Printf("recusive:%v\\n", recusive)
fmt.Printf("test:%v\\n", test)
fmt.Printf("level:%v\\n", level)
PS E:\\TEXT\\test_go\\one> go run .\\main.go -r -t hello -l 88888888
recusive:true
test:hello
level:88888888
PS E:\\TEXT\\test_go\\one>
urfave/cli 使用
安装 urfave/cli
包,属于命令行框架。
PS E:\\TEXT\\test_go\\one> go get github.com/urfave/cli
go: downloading github.com/urfave/cli v1.22.12
go: added github.com/cpuguy83/go-md2man/v2 v2.0.2
go: added github.com/russross/blackfriday/v2 v2.1.0
go: added github.com/urfave/cli v1.22.12
PS E:\\TEXT\\test_go\\one>
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
func main()
app := cli.NewApp()
app.Name = "greet"
app.Usage = "fight the loneliness!"
app.Action = func(c *cli.Context) error
fmt.Println("hello friend!")
return nil
app.Run(os.Args)
PS E:\\TEXT\\test_go\\one> go run .\\main.go
hello friend!
PS E:\\TEXT\\test_go\\one>
获取命令行参数
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
func main()
app := cli.NewApp()
app.Action = func(c *cli.Context) error
var cmd string
if c.NArg() > 0
cmd = c.Args()[0]
fmt.Println("hello friend! cmd", cmd)
return nil
app.Run(os.Args)
PS E:\\TEXT\\test_go\\one> go run .\\main.go baidu.com
hello friend! cmd baidu.com
PS E:\\TEXT\\test_go\\one>
使用 cli 框架
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
func main()
var language string
var recusive bool
app := cli.NewApp()
app.Flags = []cli.Flag
cli.StringFlag
Name: "lang, l",
Value: "english",
Usage: "select language",
Destination: &language,
,
cli.BoolFlag
Name: "recusive, r",
Usage: "recusive for the greeting",
Destination: &recusive,
,
app.Action = func(c *cli.Context) error
var cmd string
if c.NArg() > 0
cmd = c.Args()[0]
fmt.Println("cmd is ", cmd)
fmt.Println("recusive is ", recusive)
fmt.Println("language is is ", language)
return nil
app.Run(os.Args)
PS E:\\TEXT\\test_go\\one> go run .\\main.go --lang chinese
recusive is false
language is is chinese
PS E:\\TEXT\\test_go\\one>
5 实现一个简易的计算器
实现一个简易的计算器,支持加减乘除以及带括号的计算表达式,用户从终端输入表达式,程序输出计算结果。
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"github.com/urfave/cli"
)
type Stack struct
data [1024]string
top int
// Push data to stack
func (s *Stack) Push(d string)
s.data[s.top] = d
s.top++
func (s *Stack) Pop() (ret string, err error)
if s.top == 0
err = fmt.Errorf("stack is empty")
return
s.top--
ret = s.data[s.top]
return
func (s *Stack) Top() (ret string, err error)
if s.top == 0
err = fmt.Errorf("stack is empty")
return
ret = s.data[s.top-1]
return
func (s *Stack) Empty() bool
return s.top == 0
func getInput() (string, error)
reader := bufio.NewReader(os.Stdin)
return reader.ReadString('\\n')
func transPostExpress(express string) (postExpress []string, err error)
var opStack Stack
var i int
LABEL:
for i < len(express)
switch
//35+27
case express[i] >= '0' && express[i] <= '9':
var number []byte
for ; i < len(express); i++
if express[i] < '0' || express[i] > '9'
break
number = append(number, express[i])
//numStack.Push(string(number))
postExpress = append(postExpress, string(number))
case express[i] == '+' || express[i] == '-' || express[i] == '*' || express[i] == '/':
if opStack.Empty()
opStack.Push(fmt.Sprintf("%c", express[i]))
i++
continue LABEL
data, _ := opStack.Top()
if data[0] == '(' || data[0] == ')'
opStack.Push(fmt.Sprintf("%c", express[i]))
i++
continue LABEL
if (express[i] == '+' || express[i] == '-') ||
((express[i] == '*' || express[i] == '/') && (data[0] == '*' || data[0] == '/'))
//numStack.Push(data)
postExpress = append(postExpress, data)
opStack.Pop()
opStack.Push(fmt.Sprintf("%c", express[i]))
i++
continue LABEL
opStack.Push(fmt.Sprintf("%c", express[i]))
i++
case express[i] == '(':
opStack.Push(fmt.Sprintf("%c", express[i]))
i++
case express[i] == ')':
for !opStack.Empty()
data, _ := opStack.Pop()
if data[0] == '('
break
postExpress = append(postExpress, data)
//numStack.Push(data)
i++
default:
err = fmt.Errorf("invalid express:%v", express[i])
return
for !opStack.Empty()
data, _ := opStack.Pop()
if data[0] == '#'
break
postExpress = append(postExpress, data)
//numStack.Push(data)
return
func calc(postExpress []string) (result int64, err error)
var n1, n2 string
var s Stack
for i := 0; i < len(postExpress); i++
var cur = postExpress[i]
if cur[0] == '-' || cur[0] == '+' || cur[0] == '*' || cur[0] == '/'
n1, err = s.Pop()
if err != nil
return
n2, err = s.Pop()
if err != nil
return
num2, _ := strconv.Atoi(n1)
num1,<以上是关于Golang IO 操作的主要内容,如果未能解决你的问题,请参考以下文章
golang 初体验 - 令人惊叹的语法 - defer.1