golang中 os.File 库封装了文件相关操作,File是一个结构体。
go语言标准库文档:https://studygolang.com/static/pkgdoc/pkg/os.htm#File
具体的使用:
1、打开文件
1)os.Open
//Open打开一个文件用于读取。
//如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。
//如果出错,错误底层类型是*PathError。
func Open(name string) (file *File, err error)
2)os.OpenFile
OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
func OpenFile(name string, flag int, perm FileMode) (file *File, err error)
① flag参数,表示打开文件的几种模式,可用 | 符号组合使用,可用值为:
const ( O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件 O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件 O_RDWR int = syscall.O_RDWR // 读写模式打开文件 O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部 O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件 O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在 O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/O O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件 !!!谨慎使用!!! )
② FileMode参数代表文件的模式和权限位,主要使用在Linux和Unix系统下,windows系统下无效。
const ( // 单字符是被String方法用于格式化的属性缩写。 ModeDir FileMode = 1 << (32 - 1 - iota) // d: 目录 ModeAppend // a: 只能写入,且只能写入到末尾 ModeExclusive // l: 用于执行 ModeTemporary // T: 临时文件(非备份文件) ModeSymlink // L: 符号链接(不是快捷方式文件) ModeDevice // D: 设备 ModeNamedPipe // p: 命名管道(FIFO) ModeSocket // S: Unix域socket ModeSetuid // u: 表示文件具有其创建者用户id权限 ModeSetgid // g: 表示文件具有其创建者组id的权限 ModeCharDevice // c: 字符设备,需已设置ModeDevice ModeSticky // t: 只有root/创建者能删除/移动文件 // 覆盖所有类型位(用于通过&获取类型位),对普通文件,所有这些位都不应被设置 ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice ModePerm FileMode = 0777 // 覆盖所有Unix权限位(用于通过&获取类型位) )
2、关闭文件
//Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。
func (f *File) Close() error
# 例子:
//打开文件
file, err := os.Open("test.txt")
if err != nil {
fmt.Println("open file err=", err)
}
fmt.Printf("file=%v", file) //这里打印出 file=&{0xc00007a780} ,因为file是一个指针
//关闭文件file,要及时关闭文件句柄file,防止内存泄漏
defer file.Close()
3、读取文件
1)读取到file中,再利用ioutil将file直接读取到[]byte中
# 例子:
func Read1() string {
f, err := os.Open("./test.txt")
if err != nil {
fmt.Println("read file fail", err)
return ""
}
defer f.Close()
fd, err := ioutil.ReadAll(f)
if err != nil {
fmt.Println("read to fd fail", err)
return ""
}
return string(fd)
}
2)io/ioutil包中的ReadFile方法一次性读取,适用于文件不大的情况下。
这种方式下文件的Open和Close被封装到ReadFile函数内部,直接读取即可。
# 例子:
func Read2() string {
f, err := ioutil.ReadFile("./test.txt")
if err != nil {
fmt.Println("read fail", err)
}
return string(f)
}
3)使用带缓冲区的方式
func Read3() string {
file, err := os.Open("./basic/type/test.txt")
if err != nil {
fmt.Println("open file err=", err)
}
defer file.Close()
var f string
//创建一个 *Reader,带缓冲区的
//默认缓冲区为defaultBufSize = 4096
reader := bufio.NewReader(file)
//循环读取文件内容
for {
str, err := reader.ReadString('\n')
f += str
if err == io.EOF { //io.EOF表示文件的末尾
break
}
}
return f
}
4、写入文件
1)bufio.NewWriter , 可通过os.OpenFile的第二个参数灵活进行数据的覆盖、追加等。
func write1() {
filePath := "./basic/type/test1.txt"
file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
defer file.Close()
//写入文件
str := "hello world\r\n"
writer := bufio.NewWriter(file)
for i := 0; i < 5; i++ {
writer.WriteString(str)
}
//writer是带缓存的,因此在调用writerString方法时,其实内存是先写入缓存的
//Flush方法将缓存的数据真正写入文件中
writer.Flush()
}
2)ioutil.WriteFile
func write2() {
fileName := "./basic/type/test1.txt"
strTest := "测试测试"
var d = []byte(strTest)
err := ioutil.WriteFile(fileName, d, 0666)
if err != nil {
fmt.Println("write fail")
}
fmt.Println("write success")
}
5、判断文件是否存在
os.Stat
//err == nil 表示文件存在
func Stat(name string) (fi FileInfo, err error)
6、拷贝文件
io.Copy
//将src的数据拷贝到dst
func Copy(dst Writer, src Reader) (written int64, err error)
# 例子:
func CopyFile(dstFileName string, srcFileName string) (written int64, err error) {
srcFile, err := os.Open(srcFileName)
if err != nil {
fmt.Printf("open file err=%v\n", err)
}
defer srcFile.Close()
reader := bufio.NewReader(srcFile)
dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("open file err=%v\n", err)
return
}
defer dstFile.Close()
writer := bufio.NewWriter(dstFile)
return io.Copy(writer, reader)
}