Go标准库os
包提供了操纵操作系统的能力
type File struct {
*file // os specific
}
os.File
代表一个打开的文件对象句柄,即文件描述符。
os.File
类型拥有的都是指针方法,指针实现了很多io
包中的接口。对于io
包中最核心的三个接口io.Reader
、io.Writer
、io.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.Open
或os.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.ModeSocket | UNIX主机套接字 |
os.ModeSetuid | 设置uid |
os.ModeSetgid | 设置gid |
os.ModeCharDevice | UNIX字符设备,当设备模式为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
}