Go语言的IO库那么多纠结该如何选择

news2024/11/25 4:38:12

在Go语言中I/O操作的内置库有很多种,比如:io库,os库,ioutil库,bytes库,strings库等等。

io.Reader/Writer

Go语言里使用io.Reader和io.Writer两个 interface 来抽象I/O,他们的定义如下。

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

io.Reader 接口代表一个可以从中读取字节流的实体,而io.Writer则代表一个可以向其写入字节流的实体。

io.Reader/Writer 常用的几种实现

  • net.Conn:表示网络连接
  • os.Stdin,os.Stdout,os.Stderr:标准输入,输出和错误
  • os.File:网络,标准输入输出,文件的流读取
  • strings.Reader:字符串抽象成io.Reader的实现
  • bytes.Reader:[]byte抽象成io.Reader的实现
  • byte.Buffer:[]byte抽象成io.Reader和io.Writer的实现
  • bufio.Reader/Writer:带缓冲的流读取和写入(比如按行读写)

除了这几种实现外常用的还有ioutil工具库包含了很多IO工具函数,编码相关的内置库encoding/base64、encoding/binary等也是通过 io.Reader 和 io.Writer 实现各自的编码功能的。

这些常用实现和工具库与io.Reader和io.Writer间的关系可以用下图表示。

在这里插入图片描述

每种I/O库的使用场景

io库

io库属于底层接口定义库。它的作用主要是定义个I/O的基本接口和基本常量,并解释这些接口的功能。在实际编写代码做I\O操作时,这个库一般只用来调用它的常量和接口定义,比如用io.EOF判断是否已经读取完,用io.Reader做变量的类型声明。

// 字节流读取完后,会返回io.EOF这个error
for {
 n, err := r.Read(buf)
 fmt.Println(n, err, buf[:n])
 if err == io.EOF {
  break
 }
}
os库

os库主要是处理操作系统操作的,它作为Go程序和操作系统交互的桥梁。创建文件,打开或者关闭文件,Socke等等操作都是和操作系统挂钩的,所以都通过os库来执行。这个库经常和ioutil,bufio等配合使用

ioutil库

ioutil库是一个工具包,它提供了很多实用的IO工具函数,例如ReadAll,ReadFile,WriteFile,ReadDir。唯一需要注意的是它们都是一次性读取和一次性写入,所以使用时,尤其是把数据从文件里一次性读取时需要注意文件的大小。

读出文件中的所有内容

func readByFile() {
  data, err := ioutil.ReadFile( "./file/test.txt")
  if err != nil {
    log.Fatal("err:", err)
    return
  }
  fmt.Println("data", string(data)) 
}

将数据一次性写入文件

func writeFile() {
  err := ioutil.WriteFile("./file/write_test.txt", []byte("hello world!"), 0644)
  if err != nil {
    panic(err)
    return
  }
}
bufio库

bufio,可以理解为在io库的基础上额外封装加了一个缓存层,它提供了很多按行进行读取的函数,从io库的按字节读写变为按行读写对写代码来说还是方便了不少。

func readBigFile(filePath string) error {
  f, err := os.Open(filePath)
  defer f.Close()
 
  if err != nil {
    log.Fatal(err)
    return err
  }
 
  buf := bufio.NewReader(f)
  count := 0
  // 循环中打印前100行内容
  for {
    count += 1
    line, err := buf.ReadString('\n')
    line = strings.TrimSpace(line)
    if err != nil {
      return err
    }
    fmt.Println("line", line)
 
    if count > 100 {
      break
    }
  }
  return nil
}
  • ReadLine和ReadString方法:buf.ReadLine(),buf.ReadString(“\n”)都是按行读,只不过ReadLine读出来的是[]byte,后者直接读出了string,最终他们底层调用的都是ReadSlice方法。
bytes和strings库

bytes和strings库里的bytes.Reader和string.Reader,它们都实现了io.Reader接口,也都提供了NewReader方法用来从[]byte或者string类型的变量直接构建出相应的Reader实现。

r := strings.NewReader("abcde")
// 或者是 bytes.NewReader([]byte("abcde"))
buf := make([]byte, 4)
for {
 n, err := r.Read(buf)
 fmt.Println(n, err, buf[:n])
 if err == io.EOF {
  break
 }
}

另外一个区别是bytes库有Buffer的功能,而strings库则没有

var buf bytes.Buffer
fmt.Fprintf(&buf, "Size: %d MB.", 85)
s := buf.String()) // s == "Size: 85 MB."

总结

关于io.Reader和io.Writer接口,可以简单的理解为读源和写源。也就是说,只要实现了Reader中的Read方法,这个东西就可以作为读源,里面可以包含数据,被我们读取。Writer也是如此

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/65274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据图表软件-FineReport控件简介

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 -- 1.2 应用场景 在帆软报表的具体应用中,经常使用「控件」来实现不同的功能。根据使用方式可将控件分为填报控件和参数控件两大类,填报时使用的控件为填报控件,参数界面使用的控件为参…

认证服务------遇到的问题及解决方案

认证服务的问题及解决方案 问题1:发送验证码 发送验证码要注意的问题 发送验证码要注意的两个问题 1、接口防刷 接口防刷就是因为发送验证码的api接口是可以通过查看页面元素看的到的 上面就可以看到发送验证码的js代码中的请求地址,可以恶意的通过…

【产品设计】APP提升用户注册率的五个方案探讨结论

首先介绍下前置条件,我们在做产品时,出于一开始对行业特征和用户参与度的考虑,所以对注册没有要求,当用户触发需要记录用户行为的功能时才会弹出登陆注册的聚合页面,能够触发弹出的功能有:赞、写点评、回复…

ActiveMQ 笔记(九)Windows部署:单机与集群部署流程

1. 单机版部署 版本关系说明:JDK8环境只能安装5.2及以下的。超过5.2需要JDK9及以上版本环境。 (1)官网下载安装包 activemq.apache.org 选择一个版本进行下载, (2)解压安装包 下载完成之后解压 下载后直接解压缩直接就能用(免安装)。 bin/是服务启动相关的命令文件…

Xylan-PEG-NHS|木聚糖-聚乙二醇-琥珀酰亚胺

Xylan-PEG-NHS|木聚糖-聚乙二醇-琥珀酰亚胺 琥珀酰亚胺又称为丁酰亚胺或丁二酰亚胺,是一种无色针状结晶或具有淡褐色光泽的薄片固体,味甜。易溶于水、醇或氢氧化钠溶液,不溶于醚、氯仿等 中文名称:木聚糖-聚乙二醇-琥珀酰亚胺 …

目标检测 YOLOv5 开源代码项目-环境配置问题

学习视频: 目标检测 YOLOv5 开源代码项目调试与讲解实战【土堆 x 布尔艺数】 项目源码:ultralytics / yolov5 教程:手把手带你调参Yolo v5 (v6.2)(推理) 遇到的问题&解决的链接: ERROR: Failed buil…

怎样查看对方计算机网络密码,如何查看邻居家的wifi密码?不知道wifi密码怎么蹭网...

如何查看邻居家的wifi密码?不知道wifi密码怎么蹭网?不知道大家有没有遇到这样的问题:手机虽然已经连接到了WiFi,但是却已经忘记了WiFi密码。这时候如果会有一丝担忧在心中,如果下次连接不上,或是有人问你密…

[C语言数据结构]树

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录1.树1.1树的概念:1.2树与非树1.3一些关于树的概念:1.4树的一些表示方法:2.二叉树2.1概念:2.2二叉树的特点2.3满二叉树…

为什么在做微服务设计的时候一定需要DDD?

记得之前在规划和设计微服务架构的时候,张队长给了我一个至今依然记忆深刻的提示:你的设计蓝图里为什么没有看到DDD的影子呢? 随着对充血模型的领域认知的加深,我越加感觉到DDD的重要性。于是网上一顿海找,并做了学习…

Thinkpad x13 锐龙安装 Archlinux 记录

硬件配置: 笔记本影响cpu显卡内存硬盘ThinkPad X13 锐龙版r7 4750U核显16g1TB 山寨固态(大华)镜像准备 https://archlinux.org/download/ http://mirrors.163.com/archlinux/iso/2022.12.01/ 每次安装都检查iso镜像是否是网站最新的&#x…

国外数字书籍第2期

1、高级FPGA设计 (中英文版) 本书主要讲解了FPGA设计、方法和实现。这本书略去了不太必要的理论、推测未来的技术、过时工艺的细节,用简明、扼要的方式描述FPGA中的关键技术。 图1 高级FPGA设计 (克里兹)(英文版)主要内容包括:设计速度高、体积小、功耗低…

代码随想录算法训练营第五十三天|1143.最长公共子序列、1035.不相交的线、53. 最大子序和

LeetCode 1143.最长公共子序列 链接:1143.最长公共子序列 思路: 这题和上一题718. 最长重复子数组非常的像,唯一的区别就是这里的子序列可以不是连续的,既然不要求连续,我们可以在定义下标的时候不限制以特定字母结…

实战三十一:基于LightGCN推荐算法的推荐系统详细教程代码+数据

推荐系统任务描述:通过用户的历史行为(比如浏览记录、购买记录等等)构造出用户-项目交互图,协同过滤利用过去的用户-项目交互来实现预测;对相似的用户进行推荐相同喜好的item,帮助他们发现可能感兴趣的却不容易发现的item;同时将埋没在长尾中的好商品推荐给可能感兴趣的…

web前端进阶<7>:3d图像翻转效果

这几天又闲着无聊,自己学的东西又有一点不牢固了,需要写一个小程序来巩固一下,相信大家也时有同感吧!那么这一期就给大家带来一个炫酷的相册3d翻转效果,如果搭上炫酷的文字和动画那肯定是高端、霸气上档次的&#xff1…

安科瑞AF-GSM系列 智能物联网网关 支持4G/NB通讯-三防与水文监测

安科瑞 王晶淼/刘芳 1、商品描述 AF-GSM是安科瑞电气推出的新型的4G远程无线数据采集设备,采用嵌入式设计,内嵌TCP/IP协议栈,同时采用了功能强大的微处理芯片,配合内置看门狗,性能可靠稳定。 本产品提供标准RS485数…

Postman 调用 Spring Boot 文件上传接口

文章目录Postman 调用文件上传接口Postman 简介Spring Boot 定义文件上传的接口Postman 调用文件上传接口文件上传接口源码参考文献Postman 调用文件上传接口 Postman 简介 Postman 是一个用于构建和使用 API 的 API 平台。 Postman 简化了 API 生命周期的每一步,…

怎么把PDF加密?这3种方法让你轻松给PDF文件加密

现在我们的工作、学习和生活中,常会用到办公软件,其中PDF因为不易编辑,传输效果好,可以加密等特点深受大家的喜爱。我作为一个职场人,在需要分享PDF文件到人数比较多的平台时,为了不让其他人可以随意地查看…

Jnekins Active动态参数 集成Gitlab实践

参数化构建这里可以添加选项参数,一些字符串的参数,非常的多。这些参数在流水线执行的时候,它会加入到流水线里面去,最终在流水线运行的时候调用这些参数,选完参数之后再去构建。 写一段groovy脚本,然后返回…

二分查找算法【包括数组全局有序和局部有序的介绍,以及求局部最小值】

二分查找算法 二分查找要点:有序,但是一定全局有序吗?> 不一定需要全局有序 全局有序概念 一个有序的数组,通过找到 L 和 R 的中点值 ,与目标值比较,来排除一半错误的信息 时间负责度计算 32 16 8 …

Codeforces Round #787 (Div. 3) F. Vlad and Unfinished Business

翻译: Vlad和Nastya住在一个由𝑛房子和𝑛−1路组成的城市。从每一个房子,你只需要沿着路走就可以到达另一个。也就是说,城市是一棵树。 弗拉德住在索引为𝑥的房子里,娜斯提亚住在索引为&#…