Go语言 文件操作

简介: 1. 打开和关闭文件2. 读取文件2.1 defer 语句2.2 手动宕机处理2.3 打开文件并获取内容2.4 bufio 读取文件2.5 ioutil 读取文件2.6 读取奇偶行内容3. 写入文件3.1 os.OpenFile() 函数3.2 Write 和 WriteString 方式写入3.3 bufio.NewWriter 方式写入3.4 ioutil.WriteFile 方式写入

引言


计算机的文件是存储再外部介质(硬盘)上的数据集合,文件分为文本文件和二进制文件


1. 打开和关闭文件


os.open()函数能够打开一个文件,返回一个*File和一个err,对得到的文件示例close()方法能够关闭文件

close()可以释放内存空间


  • 示例:
package main
import (
  "fmt"
  "os"
)
func main() {
  //系统打开文件并赋予文件实体
  file, err := os.Open("./abc.txt")
  if err != nil {
    fmt.Println("文件打开失败", err)
  } else {
    fmt.Println("文件打开成功")
    file.Close()
    fmt.Println("文件关闭成功")
  }
}
//输出结果如下
文件打开失败 open ./abc.txt: The system cannot find the file specified.
package main
import "fmt"
func hello() {
  defer fmt.Println("执行defer") //延迟处理,函数关闭前执行
  for i := 0; i < 10; i++ {
    fmt.Println(i)
    if i == 8 {
      //手动宕机处理,立马关闭当前程序,并释放内存空间
      panic("程序宕机") //阈值
    }
  }
}
func main() {
  hello()
}


2. 读取文件


接收一个字节切片,返回读取的字节数和可能的具体错误,读到文件末尾时会返回0和 io.EOF

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


2.1 defer 语句


  • 示例:

defer—般用于资源的释放和异常的捕捉。

defer语句会将其后面跟随的语句进行延迟处理;跟在defer后面的语言将会在程序进行最后的return之后再执行

在defer归属的函数即将返回时,将延迟处理的语句按defer的逆序进行执行,也就是说,先被defer的语句最后被执行,最后被 defer 的语句,最先被执行。


package main
import "fmt"
func main() {
  defer fmt.Println("执行defer语句")  //延迟处理,函数关闭前执行
  for i := 0; i < 5; i++ {
    fmt.Println(i)
  }
}
//输出结果如下
0
1
2
3
4
执行defer语句


2.2 手动宕机处理


package main
import "fmt"
func hello() {
  defer fmt.Println("执行defer")  //延迟处理,函数关闭前执行
  for i := 0; i < 10; i++ {
    fmt.Println(i)
    if i == 8 {
      //手动宕机处理,立马关闭当前程序,并释放内存空间
      panic("程序宕机") 
    }
  }
}
func main() {
  hello()
}



2.3 打开文件并获取内容


package main
import (
  "fmt"
  "io"
  "os"
)
func main() {
  //读取文件
  file, err := os.Open("./abc.txt")
  if err != nil {
    fmt.Println("文件打开失败", err)
    return
  }
  defer file.Close()    //main函数结束前执行文件资源释放
  fmt.Println("文件打开成功")
  //定义参数切片
  var result [128]byte
  n, err := file.Read(result[:])  //以切片的形式读取
  //文件读取完成,进行判断
  if err == io.EOF {
    fmt.Println("文件读取完毕", err)
    return
  }
  //读取过程中出现异常
  if err != nil {
    fmt.Println("文件读取失败", err)
    return
  }
  fmt.Printf("字节数: %d 个\n", n)
  fmt.Printf("获取的内容是: %s", string(result[:]))
}

d314f32fc978436fa32d2c4fbac042b7.png


2.4 bufio 读取文件


使用bufio读取,bufio 在 file 的基础上封装了一层API,支持更多的功能


package main
import (
  "bufio"
  "fmt"
  "io"
  "os"
)
func main() {
  //读取文件
  file, err := os.Open("./abc.txt")
  if err != nil {
    fmt.Println("文件打开失败", err)
    return
  }
  //main函数结束前执行文件资源释放
  defer file.Close()
  //bufio缓冲区读取
  reader := bufio.NewReader(file)
  //循环读取内存,输出到程序中
  for {
    str, err := reader.ReadString('\n')   //按行读取,值赋予给str
    if err == io.EOF {
      fmt.Print(str)    //要输出,否则不显示最后一行
      // fmt.Println("文件读取完毕")
      return
    }
    if err != nil {
      fmt.Println("文件读取异常", err)
      return
    }
    fmt.Print(str)    //取消ln文件中自带换行
  }
}


ca7fe1ac1ee544dbaed2d64b3bb8cf0e.png


2.5 ioutil 读取文件


package main
import (
  "fmt"
  "io/ioutil"
)
func ReaderFile(path string) {
  content, err := ioutil.ReadFile(path)
  if err != nil {
    fmt.Println("文件读取异常")
    return
  }
  fmt.Println(string(content))  //转换string格式并输出
}
func main() {
  ReaderFile("./abc.txt")
}


cff07187630b4cb3b938a0aec04f7525.png


2.6 读取奇偶行内容


package main
import (
  "bufio"
  "fmt"
  "io"
  "os"
)
func main() {
  //读取文件
  file, err := os.Open("./abc.txt")
  if err != nil {
    fmt.Println("文件打开失败", err)
    return
  }
  //main函数结束前执行文件资源释放
  defer file.Close()
  //bufio缓冲区读取
  reader := bufio.NewReader(file)
  //计数奇偶行
  count := 0
  for {
    str, _, err := reader.ReadLine()
    count++
    if err == io.EOF {
      // fmt.Println("文件读取完毕")
      return
    }
    if err != nil {
      fmt.Println("文件读取异常", err)
      return
    }
    if count%2 == 1 {
      fmt.Println(string(str))
    }
  }
}


cff07187630b4cb3b938a0aec04f7525.png

登录并判断用户名是否存在


package main
import (
  "bufio"
  "fmt"
  "io"
  "os"
)
//读取文件
func main() {
  //var doing bool
  var name string
  fmt.Print("请输入用户名:")
  fmt.Scan(&name)
  //defer fmt.Println("用户不存在")
  file, err := os.Open("./abc.txt")
  if err != nil {
    fmt.Println("文件打开失败", err)
    return
  }
  //main函数结束前,执行文件资源释放
  defer file.Close()
  //利用bufio缓冲区读取文件
  reader := bufio.NewReader(file) //建立缓冲区,将文件内容放入到缓冲区
  //计数奇偶行
  a := 0
  for {
    str, _, err := reader.ReadLine()
    //每次读取,a+1
    a++
    if err == io.EOF {
      fmt.Println("文件读取完毕")
      //如果文件读取完,也没有返回,则说明用户不存在
      fmt.Println("用户不存在")
      return
    }
    if err != nil {
      fmt.Println("文件读取错误")
      return
    }
    if a%2 == 1 {
      if name == string(str) {
        fmt.Println("登录成功")
        return
      }
    }
  }
}

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/a444b2a6c17342a7936dce1c356e11c8.png#pic_center=600x)


3. 写入文件


3.1 os.OpenFile() 函数


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|追加|

perm:文件权限,一个八进制数。r(读)04,W(写)02,x(执行)01


3.2 Write 和 WriteString 方式写入


package main
import (
  "fmt"
  "os"
)
//使用write和writestring写入
func main() {
  //写入方式打开文件,创建新文件,开启只写模式,文件权限644
  file, err := os.OpenFile("abc.txt", os.O_CREATE|os.O_WRONLY, 0644)
  if err != nil {
    fmt.Println("文件打开失败", err)
    return
  }
  //字节切片写入
  file.Write([]byte("this is byte write\n"))
  //字符串写入
  str := "this is string write"
  file.WriteString(str)
}


397aa3ce3f164107a18e968de7fa8b28.png


3.3 bufio.NewWriter 方式写入


package main
import (
  "bufio"
  "fmt"
  "os"
)
//bufio写入
func main() {
  file, err := os.OpenFile("tmp.txt", os.O_CREATE|os.O_WRONLY, 0666)   //WRONLY,清空
  if err != nil {
    fmt.Println("文件打开失败", err)
    return
  }
  defer file.Close()
  //文件写入缓冲区
  write := bufio.NewWriter(file)
  for i := 0; i < 5; i++ {
    //内容写入缓冲区
    write.WriteString("this is bufio write\n")
  }
  //缓冲区数据提交写入文件
  write.Flush()
}


e8b0ea336cdc4ae9852966e26aa51280.png


3.4 ioutil.WriteFile 方式写入


package main
import (
  "fmt"
  "io/ioutil"
)
func main() {
  str := "this is ioutil write\nthis is test content"
  //iotuil方式直接写入,字符串转换成字节数组写入
  err := ioutil.WriteFile("./tmp.txt", []byte(str), 0666)
  if err != nil {
    fmt.Println("文件写入失败", err)
    return
  }
}


![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/e170c294440d4eb0a1de65e807fa08ab.png#pic_center=555x)

相关文章
|
8天前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
21 7
|
7天前
|
Go 开发工具
百炼-千问模型通过openai接口构建assistant 等 go语言
由于阿里百炼平台通义千问大模型没有完善的go语言兼容openapi示例,并且官方答复assistant是不兼容openapi sdk的。 实际使用中发现是能够支持的,所以自己写了一个demo test示例,给大家做一个参考。
|
8天前
|
程序员 Go
go语言中结构体(Struct)
go语言中结构体(Struct)
85 71
|
7天前
|
存储 Go 索引
go语言中的数组(Array)
go语言中的数组(Array)
91 67
|
10天前
|
Go 索引
go语言for遍历数组或切片
go语言for遍历数组或切片
82 62
|
12天前
|
并行计算 安全 Go
Go语言中的并发编程:掌握goroutines和channels####
本文深入探讨了Go语言中并发编程的核心概念——goroutine和channel。不同于传统的线程模型,Go通过轻量级的goroutine和通信机制channel,实现了高效的并发处理。我们将从基础概念开始,逐步深入到实际应用案例,揭示如何在Go语言中优雅地实现并发控制和数据同步。 ####
|
8天前
|
存储 Go
go语言中映射
go语言中映射
25 11
|
10天前
|
Go
go语言for遍历映射(map)
go语言for遍历映射(map)
24 12
|
9天前
|
Go 索引
go语言使用索引遍历
go语言使用索引遍历
17 9
|
13天前
|
安全 Serverless Go
Go语言中的并发编程:深入理解与实践####
本文旨在为读者提供一个关于Go语言并发编程的全面指南。我们将从并发的基本概念讲起,逐步深入到Go语言特有的goroutine和channel机制,探讨它们如何简化多线程编程的复杂性。通过实例演示和代码分析,本文将揭示Go语言在处理并发任务时的优势,以及如何在实际项目中高效利用这些特性来提升性能和响应速度。无论你是Go语言的初学者还是有一定经验的开发者,本文都将为你提供有价值的见解和实用的技巧。 ####