func OpenFile
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
例子:
os.OpenFile("./post.log", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
flag是设置打开模式,具体模式及含义如下:
| 模式 | 含义 |
|---|---|
| os.O_WRONLY | 只写 |
| os.O_CREATE | 创建文件 |
| os.O_RDONLY | 只读 |
| os.O_RDWR | 可读可写 |
| os.O_APPEND | 追加 |
| os.O_TRUNC | 如果可能,打开时缩短文件 |
| os.O_CREATE | 创建文件,如果文件不存在 |
| os.O_EXCL | 与创建文件一同使用,文件必须存在 |
| os.O_SYNC | 打开一个同步的文件流 |
几种常用模式
os.O_WRONLY | os.O_CREATE | O_EXCL 【如果已经存在,则失败】
os.O_WRONLY | os.O_CREATE 【如果已经存在,会覆盖写,不会清空原来的文件,而是从头直接覆盖写】
os.O_WRONLY | os.O_CREATE | os.O_APPEND 【如果已经存在,则在尾部添加写】
perm是权限控制:
-
0777:-rwxrwxrwx,创建了一个普通文件,所有人拥有所有的读、写、执行权限
-
0666:-rw-rw-rw-,创建了一个普通文件,所有人拥有对该文件的读、写权限,但是都不可执行
-
0644:-rw-r--r--,创建了一个普通文件,文件所有者对该文件有读写权限,用户组和其他人只有读权限,没有执行权限
-
r表示读,数字4. -
w表示写,数字2 -
x表示执行,数字1 -
Linux中查看文件权限一共10位,第一位d表示文件夹还是文件
创建完整目录路径,即中间目录不存在的话也一起创建
os.MkdirAll(dname,os.ModeDir|os.ModePerm)
Seek
func (f *File) Seek(offset int64, whence int) (ret int64, err error)
官方注释:Seek设置下一次读/写的位置。offset为相对偏移量,而whence决定相对位置:0为相对文件开头,1为相对当前偏移量,2为相对文件结尾。它返回新的偏移量(相对开头)和可能的错误。
偏移量一个回车算两个单位,因为在Windows系统里面,每行结尾是“<换行><回车>,即“\n\r”(在Unix系统里,每行结尾只有“<换行>”,即“\n”;而在Mac系统里,每行结尾是“<回车>”。),比如:
aa
//ret,err := f.Seek(0,2)
//ret=2
aa
a
//ret,err := f.Seek(0,2)
//ret=5
所以,如果想在文件末尾追加写入数据的写法有:
func AddPost(post Post) error {
open, err := os.OpenFile("./data/post", os.O_WRONLY, 0644)
defer open.Close()
if err != nil {
return err
}
buf, err := json.Marshal(post)//将结构体转为json
if err != nil {
return err
}
n, _ := open.Seek(0, 2) //文件结尾
_, err = open.WriteAt([]byte("\n"+string(buf)), n)
//等同于_,err = open.WriteString("\n"+string(buf))
if err != nil {
return err
}
postIndexMap[post.ParentId] = append(postIndexMap[post.ParentId], &post)
return nil
}
转自:golang文件读写