GO语言-11Go语言的I/O操作

295 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

初心是记录和总结,自己学习Go语言的历程。如果能帮助到你,这是我的荣幸。

Go语言进行I/O操作的时候是以文件的的指针*file进行操作的。I/O操作我们需要使用到os这个内置包。以常用的几个例子和注意事项,了解I/O基本操作。

以只读的方式打开文件

使用Open方法:func Open(name string) (*File, error),默认是以只读的方式打开文件。

  • 传入文件地址
  • 返回文件指针 及 error,成功打开文件的话 error 为nil,可以用来判断是否打开文件成功
func main() {
    fmt.Println("打开文件")
    open, err := os.Open("./password.txt") // 返回两个值,第一个是文件对象的指针*File,第二个是判断文件是否存在
    if err != nil {
       fmt.Println("文件打开失败,请查询原因")
       fmt.Println(err)
    }
    fmt.Println(open) // 输出的是文件的指针
    defer open.Close() // defer关键字等待最后时统一调用该方法
}

注意!使用GoLand的朋友们(和我一样的萌新):

当你没有使用命令行执行测试代码时,请注意读取文件的根路径是在working directory,如果这个位置不对的话,你很容易得到一个错误:open ./password.txt: The system cannot find the file specified.

image.png


读取文件的内容

OK!我们知道Open默认是以只读的方式打开文件了,是时候读取文件的内容了。

使用Read方法:func (f *File) Read(b []byte) (n int, err error)

  • 这里方法有接收者,是一个文件指针,刚好Open方法就返回了一个文件指针
  • 参数是需要一个byte数组,用于每次读入len(b)的内容,并将他们存在b数组中
  • 返回的第一个参数表示的是读取到的字节长度

好!看完方法,我们来理一理思路。

  1. 既然需要len(b),那我们一定要先指定好byte的长度
  2. 需要定义一个定长的数组,就像缓冲一样,每次读数组长度的内容。(等等,如果超过数组长度了呢?所以这个定长数组就是缓冲无误了)
  3. 需要定义一个切片,切片是可以无限长的(内存无限),需要将数组中读到的内容存在切片中
  4. 这涉及到循环读文件内容,终止条件是什么呢?

根据已有思路我们先写代码:

// main

    fmt.Println("读取文件")
    var buf [64]byte
    var content []byte
    for {
       n, err := open.Read(buf[:])
       if err != nil {
          fmt.Println("read file err ", err)
          return
       }
       content = append(content, buf[:n]...)
    }
    fmt.Println(string(content))

这里涉及到几个巧的方法是关于切片中取值的方式,用在了数组中

buf[:] 等于将整个数组变为了切片

buf[:n] 执行完Read方法后将读入存在buf中的内容,即时buf中有旧值也没关系。

写文件

当我尝试着使用os.的方式,我看见了这个方法名:OpenFile

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

解读:

  • name 参数和Open方法一样传入文件的地址
  • flag 这个就有点意思了见下表(常用的)
  • perm 表示如果文件不存在,那么就创建文件,并赋予文件相应的权限
内容作用说明
O_RDONLY以只读方式打开文件
O_WRONLY以只写打开文件(写入会从头覆盖原有内容)
O_RDWR以读写方式打开文件(写入会从头覆盖原有内容)
O_APPEND写入时以追加的方式(不会覆盖原有内容)
O_CREATE若文件不存在则创建文件
O_EXCL强制创建,文件必须不存在
O_SYNC以同步的方式进行I/O

例子:

file, err := os.OpenFile("./password.txt", os.O_WRONLY, 0777)
fmt.Println(file)
fmt.Println(err2)
read(file) // 封装了一个read函数,尝试去读文件时,因为设置的打开方式是O_WRONLY,所以会报错

当我们带的方式打开文件了之后,返回的文件指针就可以操作写的动作了,下面列举几个常用的

WriteString 直接写一串字符

方法:func (f *File) WriteString(s string) (n int, err error)

通过一个file指针的对象调用WriteString方法,传入一个字符串作为写入的参数,返回的是写入的长度和是否有错误产生。

注意写的时候要关注到文件指针打开文件的权限方法是什么,见上表

WriteAt 指定从哪开始写

方法:func (f *File) WriteAt(b []byte, off int64) (n int, err error)

通过一个file指针的对象调用WriteAt方法,指定从off位开始写(文件默认从0开始),将b写入文件中,返回写入长度,是否有错误。

str := "张三"
bytes := []byte(str)
fmt.Println(len(bytes))
file.WriteAt(bytes, 0)