您的当前位置:首页正文

os.File

2024-11-08 来源:个人技术集锦

Go标准库os包提供了操纵操作系统的能力

type File struct {
    *file // os specific
}

os.File代表一个打开的文件对象句柄,即文件描述符。

os.File类型拥有的都是指针方法,指针实现了很多io包中的接口。对于io包中最核心的三个接口io.Readerio.Writerio.Closer*os.File类型都实现了。

os.File类型机器指针类型的值,不但可以通过各种方式来读写文件内容,还可以寻找并设定下一次读写的起始索引位置,此外还可以随时对文件进行关闭。

要操作文件就需要先获取os.File类型的指针值,os包提供了4个获取指针值的函数。

函数返回描述
os.Create*os.File覆盖式创建
os.NewFile*os.File创建文件
os.Open*os.File打开文件
os.OpenFile*os.File打开文件

os.Create

func Create(name string) (*File, error) {
    return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}

os.Create()的函数原型是OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666),以可读写、可创建、内容清空的方式创建指定名称的文件。

文件标志位描述
O_RDWR以读写模式打开文件
O_CREATE若文件不存在则创建全新文件
O_TRUNC若可能打开时清空文件
  • os.Create()会根据给定的路径创建一个全新的文件,返回*os.File和错误值。通过返回值*os.File可以对相应文件进行读写操作。
  • 使用os.Create()创建的文件,对操作系统中所有用户都是可读写的。
  • os.Create()采用0666(任何人都可读可写不可执行)权限模式来创建文件

文件路径

  • 若给定路径的文件已存在,则会先清空现有文件中的内容,再将文件的*os.File返回。
  • 若路径不存在则会返回一个*os.PathError类型的错误值。

创建结果

  • 创建成功,会返回文件对象用于I/O操作,对应的文件描述符具有O_RDWR模式。
  • 创建失败,错误原因可能是路径不存在、权限不足、打开文件数量超过上限、磁盘空间不足等,错误底层类型为*PathError

例如:创建一个文件

tmpdir := os.TempDir()
filename := filepath.Join(tmpdir, "test.log")

file, err := os.Create(filename)
defer file.Close()
if err != nil {
    log.Fatalln(err)
}
fmt.Printf("%+v\n", file) //&{file:0xc00011e780}

file.WriteString("hello world")

buf, err := os.ReadFile(filename)
if err != nil {
    log.Fatalln(err)
}
fmt.Printf("%s\n", buf) //hello world

defer os.Remove(filename)

文件打开

os.Open

os.Open会打开一个文件用来读取

  • 若打开成功则会返回文件对象,对应的文件描述符具有O_RDONLY只读模式,使用返回的文件对象可用于读取数据。
  • 若打开出错,返回的错误对象底层类型为*PathError
func Open(name string) (*File, error) {
    return OpenFile(name, O_RDONLY, 0)
}

os.OpenFile

  • os.OpenFile是相对底层的文件打开函数,使用时建议优先采用os.Openos.Create
  • os.OpenFile支持使用指定模式和权限打开文件,打开成功则返回文件描述符可用于I/O,
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
    testlog.Open(name)
    f, err := openFileNolog(name, flag, perm)
    if err != nil {
        return nil, err
    }
    f.appendMode = flag&O_APPEND != 0

    return f, nil
}
参数描述
name文件名称,若不在当前路径下运行则需添加具体路径。
flag打开标记/打开方式/文件处理参数
perm权限控制,Windows无效。

打开标记 flag

打开标记描述
O_RDONLY以只读模式打开文件
O_WRONLY以只写模式打开文件
O_RDWR以读写模式打开文件
O_APPEND以追加模式打开文件,即写操作时将数据附加到文件末尾。
O_CREATE若文件不存在则创建
O_EXCL与O_CREATE配合用于新建文件,文件必须不存在有效,若文件存在则出错。
O_SYNC以同步方式打开,不使用缓存直接写入磁盘,在一系列写操作时每次都要等待上次I/O操作完成后才能再继续。
O_TRUNC打开时清空文件
打开标记描述
os.O_WRONLY|os.O_CREATE|os.O_EXCL若文件已存在则打开失败
os.O_WRONLY|os.O_CREATE若文件已存在则覆盖式写入,不会清空原文件,而是从头直接覆盖写入。
os.O_WRONLY|os.O_CREATE|os.O_APPEND若文件已存在则向尾部添加来写入

权限控制 perm

文件权限描述
os.ModeDir文件夹模式
os.ModeAppend追加模式
os.ModeExclusive单独使用
os.ModeTemporary临时文件
os.ModeSymlink象征性的关联
os.ModeDevice设备文件
os.NamePipe命令管道
os.ModeSocketUNIX主机套接字
os.ModeSetuid设置uid
os.ModeSetgid设置gid
os.ModeCharDeviceUNIX字符设备,当设备模式为set时。
os.ModeSticky粘性模式
os.Irregular非常规模式
os.ModeType比特位覆盖
os.ModePerm权限位

例如:创建文件并追加内容

//创建文件并追加内容
func FileAppend(name string, content string) (int, error){
    f,err := os.OpenFile(name, os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend | os.ModePerm)
    if err!=nil {
        return 0,err
    }
    defer f.Close()

    n,err := f.WriteString(content)
    if err!=nil{
        return 0, err
    }
    return n, nil
}
func main(){
    n,err := FileAppend("file.txt", "hello world")
    if err!=nil {
        fmt.Println(err)
        return
    }
    fmt.Println(n)
}
//同时创建多级目录及其下文件
func Mkfile(dirpath string, filename string, content string) error {
    err := os.MkdirAll(dirpath, os.ModePerm)
    log.Println(1, err)
    if err!=nil {
        return err
    }

    filename = path.Join(dirpath, filename)
    f,err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    log.Println(2, err)
    defer f.Close()
    if err!=nil {
        return err
    }

    _,err = f.WriteString(content)
    log.Println(3, err)
    if err!=nil {
        return err
    }

    return nil
}

关闭文件 os.Close

os.Close()用于关闭文件描述符,使文件不能读写。

func (f *File) Close() error {
    if f == nil {
        return ErrInvalid
    }
    return f.file.close()
}

文件存在

os.IsNotExist

func IsNotExist(err error) bool

例如:判断文件是否存在

//判断文件是否存在
func FileExists(file string) bool {
    _,err := os.Stat(file)
    if os.IsNotExist(err) {
        return false
    }
    return true
}

os.IsExist

func IsExist(err error) bool

例如:判断文件是否存在

//判断文件是否存在
func FileExists(file string) bool {
    if _,err := os.Stat(file); os.IsExist(err) {
        return true
    }
    return false
}
Top