golang中 os.File 库封装了文件相关操作,File是一个结构体。
go语言标准库文档:https://studygolang.com/static/pkgdoc/pkg/os.htm#File
具体的使用:
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权限位(用于通过&获取类型位) )
//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()
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 }
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") }
os.Stat
//err == nil 表示文件存在 func Stat(name string) (fi FileInfo, err error)
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) }