简析 Golang IO 包
简析 Golang IO 包
io 包提供了 I/O 原语(primitives)的基本接口。io 包中定义了四个最基本接口 Reader、Writer、Closer、Seeker 用于表示二进制流的读、写、关闭和寻址操作。这些原语和接口是对底层操作的封装,因此如没有特殊说明,这些原语和接口都不能被视为线程安全的。
Reader
Reader 接口封装了基本的 Read 方法。Read 读取长度为 len(p) 字节的数据,并写入到 p。返回结果包含读取数据字节数(0 <= n <= len(p))和 error 信息。
type Reader interface {
Read(p []byte) (n int, err error)
}
当 Read 在读取 n > 0 个字节后遇到异常或 EOF 时,Read 会返回读取的字节数。在这次读取时,可能会返回非空 error。但再一次读取,会读空并返回 error。典型的例子是,Reader 读取完全部输入流,下一次 Read 就会返回 0, EOF:
func main() {
r := strings.NewReader("some io.Reader stream to be read")
b := make([]byte, 32)
n, err := r.Read(b)
// 32, some io.Reader stream to be read, <nil>
fmt.Printf("%d, %s, %v", n, b, err)
b = make([]byte, 32)
n, err = r.Read(b)
// 0, EOF
fmt.Printf("%d, %v", n, err)
}
Read 的实现方法不建议返回 0 的同时,返回 nil error,除非 len(p) == 0。它并不代表 EOF。
常用的 Reader 接口实现有:
1.strings 包下的 Reader 类型
相关支持函数有:
- func NewReader(s string) *Reader:生产字符串 s 对应的 Reader(Read-only,未实现 Write 方法)
- func (r *Reader) Len() int:尚未被读取的字符串部分字节数
- unc (r *Reader) Read(b []byte) (n int, err error):Read 实现方法
2.bytes 包下的 Buffer 类型和 Reader 类型
Buffer 类型和 Reader 类型不同之处在于,前者实现了 Writer 接口,而后者是 read-only。
Writer
Writer 接口封装了 Write 方法。实现从缓冲区取 len(p) 字节大小的数据,写入底层数据流。如果一切正常,Write 返回 写入字节大小(n == len(p))和 nil error。否则返回 non-nil error 且 n < len(p)。
type Writer interface {
Write(p []byte) (n int, err error)
}
常用的 Writer 接口实现有:
1.strings 包下的 Builder 类型
Builder 用于高效地组建字符串,最小化消耗内存资源。
func main() {
proverbs := []string{
"Channels orchestrate mutexes serialize.",
"Cgo is not Go.",
"Errors are values.",
"Don't panic.",
}
var writer strings.Builder
for _, p := range proverbs {
n, err := writer.Write([]byte(p))
if err != nil {
fmt.Println(err)
}
if n != len(p) {
fmt.Println("failed to write data")
}
}
// 打印 Channels orchestrate mutexes serialize.Cgo is not Go.Errors are values.Don't panic.
fmt.Println(writer.String())
}
2.bytes 包下的 Buffer 类型
3.http 包下的 ResponseWriter 接口
type ResponseWriter interface {
// 返回 Header 对象,可以通过它的 Set() 方法设置头部
Header() Header
// 写入数据到 HTTP 应答报文
Write([]byte) (int, error)
// 设置返回状态码。如果没有调用这个函数,默认设置为 http.StatusOK
WriteHeader(statusCode int)
}
以下例子在 localhost:8080/handler 监听请求,并写回字符串 ”This is the HTTP response.“
func main() {
http.HandleFunc("/handler", func(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, "This is the HTTP response.\n")
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
4.go-restful 包下的 Response 类型
Response 类型封装了 http.ResponseWriter,它提供了很多便捷的方法支持写回数据。
type Response struct {
http.ResponseWriter
// contains filtered or unexported fields
}
Closer
Closer 接口封装 Close 方法。一般用于关闭文件,关闭通道,关闭连接,关闭数据库等
type Closer interface {
Close() error
}
Seeker
Seeker 接口封装 Seeker 方法。Seek 方法用于设置偏移量(offset),下一次读写便从某个特定位置开始操作数据流。和 ReaderAt、WriteAt 接口有些类似,但 Seeker 接口更灵活,可以更好的控制读写数据流的位置。
type Seeker interface {
Seek(offset int64, whence int) (int64, error)
}
偏移量 offset 的解读取决于 whence(= from where,从那里)。0 表示相对于起始位置,1 表示相对于当前的偏移,而 2 表示相对于其结尾处。以下例子,指针会移到右起倒数第五个字符的位置。所以 reader.Len() 会输出 5。
func main() {
reader := strings.NewReader("This is a test")
reader.Seek(-5, io.SeekEnd)
fmt.Printf("The unread portion of the string: %d\n", reader.Len())
}
原语组合
通过上面的四种基本接口的组合,我们可以得到多种原语组合,比如:ReadWriter、ReadCloser、WriteCloser 等。
type ReadWriter interface {
Reader
Writer
}
参考文档:
简析 Golang IO 包的更多相关文章
- JDK框架简析--java.lang包中的基础类库、基础数据类型
题记 JDK.Java Development Kit. 我们必须先认识到,JDK不过,不过一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含 ...
- 简析 Golang net/http 包
net/http 包涵盖了与 HTTP 请求发送和处理的相关代码.虽然包中定义了大量类型.函数,但最重要.最基础的概念只有两个:ServeMux 和 Handler. ServeMux 是 HTTP ...
- Golang IO包的妙用
Golang 标准库对 IO 的抽象非常精巧,各个组件可以随意组合,可以作为接口设计的典范.这篇文章结合一个实际的例子来和大家分享一下. 背景 以一个RPC的协议包来说,每个包有如下结构 type P ...
- golang io中io.go解读
目录 1. 整体大纲 2. 接口 读 写 关闭 寻址 3. 函数 读 写 复制 4. 结构体 SectionReader LimitedReader teeReader 5. 备注 根据golang ...
- Golang学习 - io 包
------------------------------------------------------------ 先说一下接口,Go 语言中的接口很简单,在 Go 语言的 io 包中有这样一个 ...
- <摘自>飞:jxl简析2 [ http://www.emlog.net/fei ]
[<摘自>飞:jxl简析:http://www.emlog.net/fei] (二)应用 在进行实践前 , 我们需要对 excel 有一个大致的了解 ,excel 文件由一个工作簿 (Wo ...
- 简析.NET Core 以及与 .NET Framework的关系
简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...
- 简析 .NET Core 构成体系
简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...
- RecycleView + CardView 控件简析
今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...
随机推荐
- 跨域问题,解决方案-Nginx反向代理
跨域问题,解决之道 跨域问题,在日常开发过程中,是一个非常熟悉的名词.今天的话题,结合我之前的项目场景,讨论下<跨域问题,解决之道>. 跨域是什么 跨域问题,是由于JavaScript出于 ...
- js鼠标滚轮事件上滚下滚判断
onmousewheel <script> var scrollFunc = function (e){ //其实我一开始也不知道用啥 //console.log(e)我们可以打印一下 / ...
- javaWeb核心技术第六篇之BootStrap
概述: Bootstrap 是最受欢迎的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB 项目. 作用: 开发响应式的页面 响应式:就是一个网站能够兼容多个终端 节约开发 ...
- 首个企业架构TOGAF角色扮演案例培训的诞生
BangEA企业架构系列在不同机构做了不少TOGAF认证课,自己都觉得有点枯燥了,我在想我们IT帮2020年第一期的认证课是不是该换种授课方式呢?想到就做......TOGAF认证培训,最早主要就是讲 ...
- .netcore 文件上传转为base64位字符串
.netcore文件上传Api接口,和正常的webForm提交类似,只是用postman测试接口时,记得给form表单命名,否则获取上传文件数量一直为0 后端代码 using System; usin ...
- JS基础语法---预解析
预解析:就是在解析代码之前 1. 预解析做什么事? 把变量的声明提前了----提前到当前所在的作用域的最上面 函数的声明也会被提前---提前到当前所在的作用域的最上面 举例: function ...
- Java - IO System类支持和缓冲流
System类的支持和缓冲流 System类对IO的支持 在System类中,为了支持IO操作提供了三个常量: 错误输出: public static final PrintStream err; 输 ...
- Django 资源 与 知识 Django中自建脚本并使用Django环境 model中的save()方法说明 filter()用法
Django 资源 与 知识 Django中自建脚本并使用Django环境 model中的save()方法说明 filter()用法 2018/11/06 Chenxin 资料说明 Django基础入 ...
- Hadoop、storm和Spark Streaming简单介绍(非原创)
文章大纲 一.Hadoop是什么二.storm是什么三.Spark Streaming是什么四.Spark与storm比较五.参考文章 一.Hadoop是什么 1. 简介 Hadoop是一个由Ap ...
- skip-broken to work around the problem rpm -Va --nofiles --nodigest
清除yum缓存 yum clean all 重新安装,见结尾[root@localhost ~]# yum install libstdc++.so.6Loaded plugins: fastestm ...