Go 语言基础之常用包【flag、time、strconv、io】(2)

简介: Go 语言基础之常用包【flag、time、strconv、io】

Go 语言基础之常用包【flag、time、strconv、io】(1)https://developer.aliyun.com/article/1534276

3、strconv

Go 语言中 strconv 包实现了基本数据类型和其字符串表示的相互转换,主要有以下常用函数: Atoi()、Itoa()、parse系列、format系列、append系列。

3.1、string 转 int(Atoi)

       为什么是 Atoi 而不是 Atos 呢?这是因为C语言中没有string类型而是用字符数组(array)表示字符串。

func main() {
  str := "100"
  num, _ := strconv.Atoi(str)
  fmt.Printf("%T,%v", num, num) // int,100
}

3.2、int 转 string(Itoa)

func main() {
  num := 100
  str := strconv.Itoa(num)
  fmt.Printf("%T,%v", str, str) // string,100
}

3.3、Parse 系列

       Parse类函数用于转换字符串给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()。

  b, _ := strconv.ParseBool("true")
  f, _ := strconv.ParseFloat("3.1415", 64)
  i, _ := strconv.ParseInt("-2", 10, 64)
  u, _ := strconv.ParseUint("2", 10, 64)

3.4、Format 系列

Format系列函数实现了将给定类型数据格式化为string类型数据的功能。

s1 := strconv.FormatBool(true)
s2 := strconv.FormatFloat(3.1415, 'E', -1, 64)
s3 := strconv.FormatInt(-2, 16)
s4 := strconv.FormatUint(2, 16)

这里需要特别说明的是:

func FormatFloat(f float64, fmt byte, prec, bitSize int) string
  • fmt 表示格式:‘f’(-ddd.dddd)、‘b’(-ddddp±ddd,指数为二进制)、’e’(-d.dddde±dd,十进制指数)、‘E’(-d.ddddE±dd,十进制指数)、‘g’(指数很大时用’e’格式,否则’f’格式)、‘G’(指数很大时用’E’格式,否则’f’格式)。
  • prec 控制精度(排除指数部分):对’f’、’e’、‘E’,它表示小数点后的数字个数;对’g’、‘G’,它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。

3.5、其它方法

func CanBackquote(s string) bool

表示返回字符串s是否可以不被修改的表示为一个单行的、没有空格和tab之外控制字符的反引号字符串。

4、文件操作

       计算机中的文件是存储在外部介质(通常是磁盘)上的数据集合,文件分为文本文件和二进制文件(音频、视频)等。

4.1、文件的打开与关闭

    // 返回文件对象指针和error对象
  file, _ := os.Open("./main.go")
  defer file.Close()

4.2、普通方式读取文件

读取文件的方法源码:

func (f *File) Read(b []byte) (n int, err error)

其中,b 是一个用于存放文件读取进来的字节,相当于是一个缓冲区,可以重复使用。

func main() {
  file, _ := os.Open("./main.go")
  defer file.Close()
 
  // 开辟一个大小为128的字节切片用来存储文件
  tmp := make([]byte, 128)
  n, err := file.Read(tmp)
  if err == io.EOF {
    fmt.Println("读取完毕")
    return
  }
  if err != nil {
    fmt.Println("读取失败")
    return
  }
  fmt.Printf("读取了%d字节的数据\n", n)
  fmt.Println(string(tmp[:n]))
}

       这种方式读取的缺点是我们并不能知道文件的大小,如果定义的缓冲区太大就浪费资源了,但是定义小了又读取不完整(因为只能读一次,不能循环利用),所以我们更多的是使用下面这种循环读取的方式:

func main() {
  file, _ := os.Open("./main.go")
  defer file.Close()
 
  var content []byte
  // 开辟一个大小为128的字节切片用来存储文件
  tmp := make([]byte, 128)
  for {
    n, err := file.Read(tmp)
    if err == io.EOF {
      fmt.Println("读取完毕")
      break
    }
    if err != nil {
      fmt.Println("读取失败")
      return
    }
    content = append(content, tmp[:n]...)
  }
  fmt.Println(string(content))
}

这种方法每次都会从文件读取 128 字节数据,Read 方法的返回值是一个切片,所以需要使用 append 函数来汇总到 content 切片当中;从下一次读取,又会把上一次的结果覆盖掉,

4.3、使用 bufio 读取文件

bufio 是在 file 的基础上封装了一层API,支持更多的功能:

func main() {
  file, _ := os.Open("./main.go")
  defer file.Close()
 
  scanner := bufio.NewScanner(file)
  for scanner.Scan() {
    fmt.Println(scanner.Text())
  }
  if err := scanner.Err(); err != nil {
    fmt.Println("读取失败", err)
  }
}

4.4、使用 os.ReadFile 读取整个文件

os包(go1.16之前是 io.ioutil )的ReadFile方法能够读取完整的文件,只需要将文件名作为参数传入:

func main() {
  content, err := os.ReadFile("./main.go")
  if err != nil {
    fmt.Println("读取失败")
    return
  }
  fmt.Println(string(content))
}

4.5、文件写入操作

os.OpenFile()函数能够以指定模式打开文件,从而实现文件写入相关功能:

func OpenFile(name string, flag int, perm FileMode) (*File, error) {
  ...
}

其中 name:要打开的文件名 flag:打开文件的模式。 模式有以下几种:

模式 含义
os.O_WRONLY  只写
os.O_CREATE 创建文件
os.O_RDONLY  只读
os.O_RDWR 读写
os.O_TRUNC 清空
os.O_APPEND 追加

4.5.1、Write 和 WriteString

func main() {
  // 0666是文件的权限设置,表示文件所有者、所属组和其他用户都有读写权限
  file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
  if err != nil {
    fmt.Println("操作文件失败", err)
    return
  }
  defer file.Close()
  str := "Hello let's Go\n"
  file.Write([]byte(str))
  file.WriteString("Hello Big Data")
}

运行结果:

4.5.2、bufio.NewWriter

效果都是一样的,只不过是不同包下的方法:

func main() {
  // 0666是文件的权限设置,表示文件所有者、所属组和其他用户都有读写权限
  file, err := os.OpenFile("./test.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
  if err != nil {
    fmt.Println("操作文件失败", err)
    return
  }
  defer file.Close()
  writer := bufio.NewWriter(file)
  for i := 0; i < 10; i++ {
    writer.WriteString("Hello let's Go\n") //将数据先写入缓存
  }
  writer.Flush() // 将缓存中的内容写入文件
}

4.5.3、os.WriteFile

       os 包(go1.16之前是 io.ioutil )下的 WriteFile 可以一次将一个byte切片内的数据全部写入文件当中。只不过不能指定写入模式,比如追加等。

func main() {
  str:="Hello let's Go"
  err := os.WriteFile("./test.txt", []byte(str), 0666)
  if err != nil {
    fmt.Println("写入失败")
    return
  }
}
相关文章
|
3天前
|
存储 JSON 监控
Viper,一个Go语言配置管理神器!
Viper 是一个功能强大的 Go 语言配置管理库,支持从多种来源读取配置,包括文件、环境变量、远程配置中心等。本文详细介绍了 Viper 的核心特性和使用方法,包括从本地 YAML 文件和 Consul 远程配置中心读取配置的示例。Viper 的多来源配置、动态配置和轻松集成特性使其成为管理复杂应用配置的理想选择。
16 2
|
5天前
|
程序员 Go
go语言中的控制结构
【11月更文挑战第3天】
81 58
|
4天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
1天前
|
Go
go语言中的 跳转语句
【11月更文挑战第4天】
9 4
|
1天前
|
JSON 安全 Go
Go语言中使用JWT鉴权、Token刷新完整示例,拿去直接用!
本文介绍了如何在 Go 语言中使用 Gin 框架实现 JWT 用户认证和安全保护。JWT(JSON Web Token)是一种轻量、高效的认证与授权解决方案,特别适合微服务架构。文章详细讲解了 JWT 的基本概念、结构以及如何在 Gin 中生成、解析和刷新 JWT。通过示例代码,展示了如何在实际项目中应用 JWT,确保用户身份验证和数据安全。完整代码可在 GitHub 仓库中查看。
11 1
|
1天前
|
Go 索引
go语言中的循环语句
【11月更文挑战第4天】
8 2
|
1天前
|
Go C++
go语言中的条件语句
【11月更文挑战第4天】
10 2
|
5天前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
5天前
|
Go 数据处理 调度
探索Go语言的并发模型:Goroutines与Channels的协同工作
在现代编程语言中,Go语言以其独特的并发模型脱颖而出。本文将深入探讨Go语言中的Goroutines和Channels,这两种机制如何协同工作以实现高效的并发处理。我们将通过实际代码示例,展示如何在Go程序中创建和管理Goroutines,以及如何使用Channels进行Goroutines之间的通信。此外,本文还将讨论在使用这些并发工具时可能遇到的常见问题及其解决方案,旨在为Go语言开发者提供一个全面的并发编程指南。
|
3天前
|
Go 调度 开发者
探索Go语言中的并发模式:goroutine与channel
在本文中,我们将深入探讨Go语言中的核心并发特性——goroutine和channel。不同于传统的并发模型,Go语言的并发机制以其简洁性和高效性著称。本文将通过实际代码示例,展示如何利用goroutine实现轻量级的并发执行,以及如何通过channel安全地在goroutine之间传递数据。摘要部分将概述这些概念,并提示读者本文将提供哪些具体的技术洞见。