文件操作

144 阅读2分钟

func OpenFile

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

OpenFile是一个更一般性的文件打开函数,大多数调用者都应用OpenCreate代替本函数。它会使用指定的选项(如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

}

OS中文文档

转自:golang文件读写