猜谜游戏作业中涉及的golang输入输出| 青训营笔记

139 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第 1 篇笔记

前言

  在猜词小游戏当中,我看到 示例源码 的输入处理方式是使用 bufio.NewReader 来做的。

  其实 golang 一般的输入方式是用 scanf 函数,与 c/c++ 的 scanf 类似

  

fmt 输入

fmt.Scan

  fmt.Scan交互式接受输入,通过空格来分词。调用Scan函数时,要指定接收输入的变量名和变量数。

  直到接收完所有指定的变量数,Scan函数才会返回,回车符也无法提前让它返回。

func main() {
	var (
		num  int
		name string
	)
	fmt.Scan(&num, &name)
	fmt.Println(num, name)
}

  

fmt.Scanln

  Scanln调用时,也要指定接收输入的变量名和变量数。

  它同Scan的区别,在于\ n会让函数提前返回,将返回时还未接收到值的变量赋为空。

func main() {
	var bfirstName, bsecondName string
	fmt.Println("Please enter the firstName and secondName: ")

	fmt.Scanln(&bfirstName, &bsecondName)

	fmt.Printf("firstName is %s, secondName is %s\n", bfirstName, bsecondName)
}


Please enter the firstName and secondName:
de
firstName is de, secondName is 

  

  

fmt.Scanf

  用Scanf处理输入,是比较灵活的一种处理方式。

  需要指定输入的格式,适用于完全了解输入格式的场景,可以直接把不需要的部分过滤掉。

fmt.Println("Please enter the firstName and secondName: ")

fmt.Scanf("//%s\n%s", &cfirstName, &csecondName)

fmt.Printf("firstName is %s, secondName is %s", cfirstName, csecondName)

  结果如下:

  1)这个场景,在接收输入时,就把不需要的部分“//” 和 “\n”过滤掉了,接收到是有用的两个字符串zz和rr。

Please enter the firstName and secondName:

//zz

rr

firstName is zz, secondName is rr

  2)如果输入不符合指定的格式,从不符合处开始,其后的变量值都为空。

Please enter the firstName and secondName:

//zr ui

firstName is zr, secondName is

  

  


  

bufio 输入

简介

  bufio:从 buf 前缀可以看出,这是一个与 buffer (缓冲) 相关的 IO 操作标准库

  可以类比 Java 的 "BufferedReaderStream and BufferedWriterStream"[^1]

  通过缓冲来提高读写效率

  • io操作本身的效率并不低,低的是频繁的访问本地磁盘的文件。所以bufio就提供了缓冲区(分配一块内存),读和写都先在缓冲区中,最后再读写文件,来降低访问本地磁盘的次数,从而提高效率。

  

  简单的说就是,把文件读取进缓冲(内存)之后再读取的时候就可以避免文件系统的io 从而提高速度。同理,在进行写操作时,先把文件写入缓冲(内存),然后由缓冲写入文件系统。

  缓冲区的设计是为了存储多次的写入,最后一口气把缓冲区内容写入文件。

v2-eafcc5129ec4afd2ed89cecc5824c57e_1440w-20220506145205-5pi424d.jpg

  

  bufio 封装了io.Reader或io.Writer接口对象,并创建另一个也实现了该接口的对象。

  

以下简单说一下如何使用

  

io.Reader

  bufio 包提供了两个实例化 bufio.Reader 对象的函数:NewReader 和 NewReaderSize。其中,NewReader 函数是调用 NewReaderSize 函数实现的:

    func NewReader(rd io.Reader) *Reader {
        // 默认缓存大小:defaultBufSize=4096
        return NewReaderSize(rd, defaultBufSize)
    }

  

  我们先创建一个 reader,然后调用里面的方法

   image-20220506145716-kxiemos.png

  • 可以看到,读取的方法很多

  

  猜字游戏中使用的是 ReadString 方法

func main() {
	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	if err != nil {
		panic(errors.New("输入失败"))
	}

	fmt.Println(input)
}
  • readString 中输入的参数是 delim:表示用什么字符进行划分
  • \n 表示用空格进行划分字符

  

  

io.Writer

  writer 主要用于写文件操作

  

示例代码

func main() {
	var (
		fileName = "D:/test.txt"
		content  = "Hello golang"
		file     *os.File
		err      error
	)

	// 使用追加模式打开文件
	file, err = os.OpenFile(fileName, os.O_APPEND, 0666)
	if err != nil {
		panic(errors.New("打开文件失败"))
	}
	defer file.Close() // 养成好习惯,打开资源后紧跟着defer关闭

	// 写文件
	writer := bufio.NewWriter(file)
	n, err := writer.Write([]byte(content))
	if err != nil {
		panic(errors.New("写入文件失败"))
	}
	fmt.Println("写入文件成功,文件长度为 = ", n)
	writer.Flush() // 刷新

}

  

  

  


  

小结

  以上只是做作业过程中的临时记录,后面有时间会补充缺失的内容