IO 操作的基本分类

在计算机中,处理文件和网络通讯等,都需要进行 IO 操作,IO 即是 input/ouput,计算机的输入输出操作。

Go语言中的 IO 操作封装在如下几个包中:

当然除了上面这些,还有一些比如 json,xml,tar 等也属于文件操作。

其中 io 包中的 io.Readerio.Writer 比较关键。io.Reader 接口实现了对文件、套接字等输入设备的抽象;io.Writer 接口则实现了对输出设备的抽象。

io 包提供了很多功能,这个包可以以流式的方式高效处理数据,而不用考虑数据是什么,数据来自哪里,以及数据要发送到哪里去。只要你实现了这2个接口。这就是抽象的能力。

IO包2个重要接口 Reader 和 Writer

在 io 包中有 2 个重要的接口:io.Readerio.Writer

实现了这2个接口,就可以使用 io 包的功能。

Reader 接口

type Reader interface {
Read(p []byte) (n int, err error)
}

Read() 方法将 len(p) 个字节读取到 p 中。它返回读取的字节数 n,以及发生错误时的错误信息。

  1. 如果读到了数据(n > 0),则 err 应该返回 nil。
  2. 如果数据被读空,没有数据可读(n == 0),则 err 应该返回 EOF。
  3. 如果遇到读取错误,则 err 应该返回相应的错误信息。
  4. n 可能小于 len(p),也就是说在 Go 读取 IO 时,是不会保证一次读取预期的所有数据的。
  5. 如果要保证读取所需的所有数据,就需要在一个循环里调用 Read,累加每次返回的数据。

只要某个实例实现了接口 io.Reader 里的方法 Read() ,就满足了接口 io.Reader ,可以当做参数传入进来。

io.EOF 变量的定义:var EOF = errors.New("EOF"),是 error 类型。根据 reader 接口的说明,在 n > 0 且数据被读完了的情况下,当次返回的 error 有可能是 EOF 也有可能是 nil。

例子1: demo_reader.go 从标准输入中读取数据

package main

import (
"fmt"
"io"
"os"
) func ReadFrom(reader io.Reader, num int) ([]byte, error) {
p := make([]byte, num)
n, err := reader.Read(p) fmt.Println("n: ", n) if n > 0 {
return p[:n], nil
}
return p, err
} func main() {
for {
data, err := ReadFrom(os.Stdin, 4)
if err != nil {
if err == io.EOF {
break
}
} else {
fmt.Printf("receive: %X, %s\n", data, string(data))
}
}
}

Writer 接口

type Writer interface {
Write(p []byte) (n int, err error)
}

Write 方法将 len(p) 个字节从 p 中写入到对象数据流中。它返回从 p 中被写入的字节数 n,以及发生错误时返回的错误信息。

  1. 如果 p 中的数据全部被写入,则 err 应该返回 nil。
  2. 如果 p 中的数据无法被全部写入,则 err 应该返回相应的错误信息。

例子1 :demo_writer.go

package main

import (
"bytes"
"fmt"
"os"
) func main() {
// 创建 Buffer 暂存空间,并将一个字符串写入 Buffer
// 使用 io.Writer 的 Write 方法写入
var buf bytes.Buffer
buf.Write([]byte("hello world , ")) // 用 Fprintf 将一个字符串拼接到 Buffer 里
fmt.Fprintf(&buf, " welcome to golang !") // 将 Buffer 的内容输出到标准输出设备
buf.WriteTo(os.Stdout)
}

bytes.Buffer 结构体:

bytes.Buffer 是一个结构体类型,用来暂存写入的数据,这个结构体实现了 io.Writer 接口的 Write 方法。

Fprintf 方法定义:

func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)

第一个参数是 io.Writer 接口类型,bytes.Buffer 结构体实现了 io.Writer 接口里的 Write 方法,实现了 Write 方法的类型都可以作为参数(这里是 buf)传入。

WriteTo 方法定义:

func (b *Buffer) WriteTo(w io.Writer) (n int64, err error)

WriteTo 方法第一个参数是 io.Writer 接口类型。

例子1:file_write.go

package main

import (
"fmt"
"os"
) func main() {
strings := []string{
"hello, golang! \n",
"welcome to golang! \n",
"Go is a good lang. ",
} file, err := os.Create("./writefile.txt")
if err != nil {
fmt.Println(err)
os.Exit(1)
} defer file.Close() for _, p := range strings {
// file 类型实现了 io.Writer
n, err := file.Write([]byte(p))
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if n != len(p) {
fmt.Println("failed to write data")
os.Exit(1)
}
} fmt.Println("file wirte done")
}

把 strings 这个 slice 结构中的字符串写入到名为 writefile.txt 的文件中。

参考

Go package(3):io包介绍和使用的更多相关文章

  1. IO与文件读写---使用Apache commons IO包提高读写效率

    觉得很不错,就转载了, 作者: Paul Lin 首先贴一段Apache commons IO官网上的介绍,来对这个著名的开源包有一个基本的了解:Commons IO is a library of ...

  2. 家庭洗车APP --- Androidclient开展 之 网络框架包介绍(一)

    家庭洗车APP --- Android客户端开发 之 网络框架包介绍(一) 上篇文章中给大家简单介绍了一些业务.上门洗车APP --- Android客户端开发 前言及业务简单介绍,本篇文章给大家介绍 ...

  3. Lucene3.6.2包介绍,第一个Lucene案例介绍,查看索引信息的工具lukeall介绍,Luke查看的索引库内容,索引查找过程

    2.Lucene3.6.2包介绍,第一个Lucene案例介绍,查看索引信息的工具lukeall介绍,Luke查看的索引库内容,索引查找过程 2014-12-07 23:39 2623人阅读 评论(0) ...

  4. java.io包详细解说

    转自:http://hzxdark.iteye.com/blog/40133 hzxdark的博客 我不知道各位是师弟师妹们学java时是怎样的,就我的刚学java时的感觉,java.io包是最让我感 ...

  5. apache commons io包基本功能

    1. http://jackyrong.iteye.com/blog/2153812 2. http://www.javacodegeeks.com/2014/10/apache-commons-io ...

  6. IO 多路复用介绍

    IO多路复用 概念说明 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 I/O 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系 ...

  7. python 全栈开发,Day44(IO模型介绍,阻塞IO,非阻塞IO,多路复用IO,异步IO,IO模型比较分析,selectors模块,垃圾回收机制)

    昨日内容回顾 协程实际上是一个线程,执行了多个任务,遇到IO就切换 切换,可以使用yield,greenlet 遇到IO gevent: 检测到IO,能够使用greenlet实现自动切换,规避了IO阻 ...

  8. {python之IO多路复用} IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO模型比较分析 selectors模块

    python之IO多路复用 阅读目录 一 IO模型介绍 二 阻塞IO(blocking IO) 三 非阻塞IO(non-blocking IO) 四 多路复用IO(IO multiplexing) 五 ...

  9. 7.1 安装软件包的三种方法 7.2 rpm包介绍 7.3 rpm工具用法 7.4 yum工具用法 7.5 yum搭建本地仓库

    7.1 安装软件包的三种方法 7.2 rpm包介绍 7.3 rpm工具用法 7.4 yum工具用法 7.5 yum搭建本地仓库 三种方法 rpm工具----->类型windows下的exe程序 ...

随机推荐

  1. 学习java的第十三天

    一.今日收获(前两天家里有事,博客都忘了发了,唉) 1.通过看哔哩哔哩看黑马程序员的教学视频,学习了java中的数据类型自动转换.强制转换及注意事项三节 2.简单看了看完全学习手册 二.今日问题 1. ...

  2. nodejs-Express框架

    JavaScript 标准参考教程(alpha) 草稿二:Node.js Express框架 GitHub TOP Express框架 来自<JavaScript 标准参考教程(alpha)&g ...

  3. 百度 IP 查询

    查询 IP 地址以及百度爬虫 IP 我们如果要查询 IP 地址,互联网上有很多提供IP查询服务的网站,我这里总结和归纳如下: 国内提供 IP 查询的网站: IP138 IPIP,提供 IP 详细信息, ...

  4. C逗号表达式

    c语言提供一种特殊的运算符,逗号运算符,优先级别最低,它将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值.如:(3+5,6+8)称为逗号表达式,其求解过程先表达 ...

  5. Linux基础命令---host域名查询工具

    host host是一个常用的DNS查询工具,经常用来查询域名.检查域名解析是否正确. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.Fedora.   1.语法       ...

  6. [学习总结]7、Android AsyncTask完全解析,带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴 ...

  7. 【Matlab】求矩阵行和/列和

    行和 sum(a, 2) 列和 sum(a) 所有元素之和 sum(sum(a)) 某一列元素之和 sum(a(:,1)) %a矩阵的第一列之和 某一行元素之和 sum(a(1,:)) %a矩阵的第一 ...

  8. 论文翻译:2021_A Perceptually Motivated Approach for Low-complexity, Real-time Enhancement of Fullband Speech

    论文地址:一种低复杂度实时增强全频带语音的感知激励方法 论文代码 引用格式:A Perceptually Motivated Approach for Low-complexity, Real-tim ...

  9. [BUUCTF]PWN——[V&N2020 公开赛]simpleHeap

    [V&N2020 公开赛]simpleHeap 附件 步骤: 例行检查,64位,保护全开 根据题目可知是一道堆,直接用64位ida打开 我修改了这些函数的名称,这样方便看程序 add,我们可以 ...

  10. LuoguP4759 [CERC2014]Sums 题解

    Content 给定 \(t\) 组数据,每组数据给定一个数 \(n\),判断 \(n\) 是否能够分解成连续正整数和,能的话给出最小数最大的方案. 数据范围:\(1\leqslant n\leqsl ...