大家好,欢迎来到IT知识分享网。
移动数据是您在编程时最常见的事情之一。这就是为什么无论你使用什么语言,你都必须掌握处理数据流。
我今天开始一个关于在Go中与I/O合作的小系列。
第一部分旨在让您进入正确的心态,并为您提供足够大的最小工具集,使您变得危险。
一切都是一堆字节
有人在Linkedin上抱怨说,len给出字节数,而不是字符串的字符数,这令人困惑:
包裹主 导入“fmt” func main() { str := "ana" fmt.Println(len(str)) // 3 str = "世界" fmt.Println(len(str)) // 6 不是 2 }
由于错误的心理模式,这可能会让某人感到困惑。在计算中,每条数据都只是一系列字节。如果您想要它的长度,那么您需要字节数,而不是该数据中解释的事物数。
如果我在Go中加载以下图像并在数据上运行len,我将不会得到1,因为图片中有1只猫,而是,因为图像有字节。
![Go中的I/O基础知识插图1 Go中的I/O基础知识](https://yundeesoft.com/wp-content/uploads/2022/11/2022112316405970.jpg)
个可爱的字节
请记住:您正在操作的每个数据,无论是字符串、图像还是文件,都只是一堆字节。
读者和作家
数据移动包括两个基本部分:阅读和写作。你从某个地方阅读,应用一些转换或其他东西,然后,你把最终数据写到某个地方。
由于阅读和写作是基本操作,Go为我们提供了两个抽象概念:io.Reader和io.Writer。从现在开始,为了可读性,我将称他们为读者和作家。
记住:读者是你可以阅读的东西,而作家是你可以写作的东西。
我强调这一点,因为当我从Go开始时,这个命名让我感到困惑。
当我听到一个作家时,我就会想到一个写作的人。但在围棋中,作家是你可以写信给的东西。
![Go中的I/O基础知识插图3 Go中的I/O基础知识](https://yundeesoft.com/wp-content/uploads/2022/11/2022112316405970.jpg)
哪一个是作者?
在Go中定义接口时,您不会定义什么,而是定义它提供了什么——行为,而不是事物!这是我的误会。
例如,我们没有带有读写方法的文件接口,但我们有由具体文件类型实现的Reader和Writer接口
在Go中与I/O合作时,你不在乎某物是什么,而是你是否能从中读取或写入它。
只要它实现了Reader接口,你就可以从中读取,如果它实现了Writer接口,你就可以写入它。
如果你有一些字节,你可以把它们写给任何作家。字节代表文件、网络连接、HTTP响应还是其他东西并不重要。
最小I/O工具包
现在,让我们按照承诺将第一批类型和功能添加到我们的工具集中。
字节。缓冲区
正如我上面所说,每条数据都只是一堆字节。通常,这表示为[]byte,但字节的切片不实现Reader和Writer接口。
我经常使用的一种类型是字节。缓冲区,因为它就像一个[]byte,实现了Reader和Writer接口,简化了对它的读取和写入。
io.复制
你有读者吗,想把内容复制给作家吗?io.Copy能奏效!
我们创建一个缓冲区,在其中添加一个字符串,然后复制该数据toosos.Stdout,最后只是一个文件:
包裹主 进口( 字节 "io" "os" ) func main() { var buf bytes.Buffer buf.WriteString("hello world\n") io.Copy(os.Stdout,&buf) }
fmt.Fprint
有时你只是想给作家打印一些字符串。为此,您可以使用fmt.Fprint%函数:
包裹主 进口( 字节 "fmt" "os" ) func main() { var buf bytes.Buffer // 可以调用Fprintf将字符串打印到任何io.Writer fmt.Fprintf(&buf,“你好,世界!”)// 在字节.Buffer上 fmt.Println(buf.String()) fmt.Fprintf(os.Stdout,世界你好!\n") // 在*os.File上 }
当我编写网络服务器时,我也喜欢这些功能。/health端点可以像这样简单:
包裹处理程序 进口( "fmt" "net/http" ) func HealthHandler() http.Handler { 返回http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "OK") // 将 OK 字符串写入响应主体 }, ) }
由于您可以直接写入响应主体,因此在浏览器中进行打印调试也很方便。
io.全部阅读
当您想从某个阅读器读取所有字节时,此方法非常有用:
包裹主 进口( "fmt" "io" 弦乐 ) func main() { r := strings.NewReader(“你好,世界!”) 数据,_ := io.ReadAll(r) fmt.Println(data) // [72 101 108 108 111 32 87 111 114 108 100 33] fmt.Println(string(data)) // 你好,世界! }
如果您正在处理一个巨大的文件,立即阅读完整内容可能并不总是一个好主意。我们将在未来的帖子中看到我们有什么替代方案。然而,io.ReadAll是工具包中非常方便的功能。
结论
总结一下,以下是本文涵盖的最重要信息:
在基本层面上,每个数据都只是一堆字节。
我们在编程时所做的大部分工作都是移动数据。
移动数据由两部分组成:阅读和写作。Go为这些操作提供了usioio.Reader和io.Writer抽象。
读者是你可以阅读的东西,作家是你可以写信给的东西。
只要某样东西实现了io.Reader,你就可以从中读取,如果它实现了io.Writer,你就可以写给它。
我们还在我们的工具包中添加了一堆有用的类型和功能:
io.Reader和io.Writer
字节。缓冲区
io.复制
fmt.Fprintf和fmt.Fprintln
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/75333.html