初心是记录和总结,自己学习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.
读取文件的内容
OK!我们知道Open
默认是以只读的方式打开文件了,是时候读取文件的内容了。
使用Read
方法:func (f *File) Read(b []byte) (n int, err error)
- 这里方法有接收者,是一个文件指针,刚好
Open
方法就返回了一个文件指针 - 参数是需要一个byte数组,用于每次读入len(b)的内容,并将他们存在b数组中
- 返回的第一个参数表示的是读取到的字节长度
好!看完方法,我们来理一理思路。
- 既然需要len(b),那我们一定要先指定好byte的长度
- 需要定义一个定长的数组,就像缓冲一样,每次读数组长度的内容。(等等,如果超过数组长度了呢?所以这个定长数组就是缓冲无误了)
- 需要定义一个切片,切片是可以无限长的(内存无限),需要将数组中读到的内容存在切片中
- 这涉及到循环读文件内容,终止条件是什么呢?
根据已有思路我们先写代码:
// 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)