读取用户的输入
从键盘和标准输入 os.Stdin 读取输入,最简单的办法是使用 fmt 包提供的 Scan 和 Sscan 开头的函数。
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.Printf("Hi firstName: %s, lastName: %s!\n", firstName, lastName)
fmt.Sscanf(input, format, &f, &i, &s)
fmt.Println("From the string we read: ", f, i, s)
}
Please enter your full name:
eric wang
Hi firstName: eric, lastName: wang!
From the string we read: 56.12 5212 Go
Scanln 扫描来自标准输入的文本,将空格分隔的值依次存放到后续的参数内,直到碰到换行。Sscan 和以 Sscan 开头的函数则是从字符串读取文本。
bufio
也可以使用 bufio 包提供的缓冲读取(buffered reader)来读取数据。
import (
"fmt"
"bufio"
"os"
)
var (
inputReader *bufio.Reader
input string
err error
)
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)
}
Please enter some input:
this is input!
The input was: this is input!
读取器对象提供 ReadString(delim byte) 从输入中读取内容,直到碰到 delim 指定的字符,然后将读取到的内容连同 delim 字符一起放到缓冲区。ReadString 返回读取到的字符串,如果碰到错误则返回 nil。如果它一直读到文件结束,则返回读取到的字符串和 io.EOF。如果读取过程中没有碰到 delim 字符,将返回错误 err != nil。
文件读写
读取文件
利用 ioutil.ReadFile 直接从文件读取到 []byte 中。
import (
"fmt"
"io/ioutil"
)
func main() {
f, err := ioutil.ReadFile("file/test")
if err != nil {
panic(err)
}
fmt.Println(string(f))
}
先从文件读取到 file 中,再从 file 读取到 buf,buf 再追加到最终的 []byte。
import (
"fmt"
"io"
"os"
)
func main() {
// 获得一个 file
f, err := os.Open("file/test")
if err != nil {
panic(err)
}
// 把 file 读取到缓冲区中
defer f.Close()
var chunk []byte
buf := make([]byte, 1024)
for {
// 从 file 读取到 buf 中
n, err := f.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
// 说明读取结束
if n == 0 {
break
}
// 读取到最终的缓冲区中
chunk = append(chunk, buf[:n]...)
}
fmt.Println(string(chunk))
}
先从文件读取到 file 中,再从 file 读取到 Reader 中,从 Reader 读取到 buf,buf 最终追加到 []byte。
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
func main() {
fi, err := os.Open("file/test")
if err != nil {
panic(err)
}
defer fi.Close()
r := bufio.NewReader(fi)
var chunks []byte
buf := make([]byte, 1024)
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
panic(err)
}
if n == 0 {
break
}
chunks = append(chunks, buf...)
}
fmt.Println(string(chunks))
for {
line, err := r.ReadString('\n')
if err != nil {
if err == io.EOF {
fmt.Println("File read ok!")
break
} else {
panic(err)
}
}
line = strings.TrimSpace(line)
fmt.Println(line)
}
}
读取到 file 中,再利用 ioutil 将 file 直接读取到 []byte 中。
import (
"fmt"
"io/ioutil"
"os"
)
func main() {
f, err := os.Open("file/test")
if err != nil {
panic(err)
}
defer f.Close()
fd, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
fmt.Println(string(fd))
}
使用 fmt 包提供的以 FScan 开头的一系列函数来读取文件。
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("test.txt")
if err != nil {
panic(err)
}
defer file.Close()
var col1, col2, col3 []string
for {
var v1, v2, v3 string
_, err := fmt.Fscanln(file, &v1, &v2, &v3)
// scans until newline
if err != nil {
break
}
col1 = append(col1, v1)
col2 = append(col2, v2)
col3 = append(col3, v3)
}
fmt.Println(col1)
fmt.Println(col2)
fmt.Println(col3)
}
[ABC FUNC GO]
[40 56 45]
[150 280 356]
写入文件
使用 io.WriteString 写入文件。
import (
"fmt"
"io"
"os"
)
func main() {
fileName := "file/test"
strTest := "测试测试"
var f *os.File
var err error
if CheckFileExist(fileName) { // 文件存在
f, err = os.OpenFile(fileName, os.O_APPEND, 0666) // 打开文件
if err != nil {
panic(err)
}
} else { // 文件不存在
f, err = os.Create(fileName) // 创建文件
if err != nil {
panic(err)
}
}
// 将文件写进去
n, err := io.WriteString(f, strTest)
if err != nil {
panic(err)
}
fmt.Println("写入的字节数是:", n)
}
func CheckFileExist(fileName string) bool {
_, err := os.Stat(fileName)
return os.IsNotExist(err)
}
使用 ioutil.WriteFile 写入文件。
import (
"fmt"
"io/ioutil"
)
func main() {
fileName := "file/test"
strTest := "测试测试"
var d = []byte(strTest)
err := ioutil.WriteFile(fileName, d, 0666)
if err != nil {
panic(err)
}
fmt.Println("write success")
}
使用 File(Write, WriteString) 写入文件。
import (
"fmt"
"os"
)
func main() {
fileName := "file/test"
strTest := "测试测试"
var d1 = []byte(strTest)
f, err := os.Create(fileName) // 创建文件
if err != nil {
panic(err)
}
defer f.Close()
n1, err := f.Write(d1) // 写入文件(字节数组)
if err != nil {
panic(err)
}
fmt.Printf("写入 %d 个字节", n1)
n2, err := f.WriteString("writesn") // 写入文件(字符串)
if err != nil {
panic(err)
}
fmt.Printf("写入 %d 个字节", n2)
f.Sync()
}
使用 bufio.NewWriter 写入文件。
import (
"bufio"
"fmt"
"os"
)
func main() {
fileName := "file/test"
f, err := os.Create(fileName) // 创建文件
if err != nil {
panic(err)
}
defer f.Close()
w := bufio.NewWriter(f) // 创建新的 Writer 对象
n, err := w.WriteString("bufferedn")
if err != nil {
panic(err)
}
fmt.Printf("写入 %d 个字节", n)
w.Flush()
}
复制文件
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.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}
从命令行读取参数
os
os 包中有一个 string 类型的切片变量 os.Args,用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。
import (
"fmt"
"os"
"strings"
)
func main() {
who := "Alice "
if len(os.Args) > 1 {
who += strings.Join(os.Args[1:], " ")
}
fmt.Println("Good Morning", who)
}
命令行参数会放置在切片 os.Args[] 中(以空格分隔),从索引 1 开始(os.Args[0] 放的是程序本身的名字)。
flag
import (
"flag"
"os"
)
var NewLine = flag.Bool("n", false, "print newline") // echo -n flag, of type *bool
const (
Space = " "
Newline = "\n"
)
func main() {
flag.PrintDefaults()
flag.Parse() // Scans the arg list and sets up flags
var s string = ""
for i := 0; i < flag.NArg(); i++ {
if i > 0 {
s += Space
if *NewLine { // -n is parsed, flag becomes true
s += Newline
}
}
s += flag.Arg(i)
}
os.Stdout.WriteString(s)
}
go run main.go -n=true eric wang
-n print newline
eric
wang
flag.Parse() 扫描参数列表(或者常量列表)并设置 flag,flag.Arg(i) 表示第 i 个参数。Parse() 之后 flag.Arg(i) 全部可用,flag.Arg(0) 就是第一个真实的 flag,而不是像 os.Args(0) 放置程序的名字。
flag.Bool() 定义了一个默认值是 false 的 flag,当在命令行出现第一个符合的参数,flag 被设置成 true。flag 被解引用到 *NewLine,所以当值是 true 时将添加一个 Newline。
flag.PrintDefaults() 打印 flag 的使用帮助信息。