golang 文件的基本操作

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)
}
上一篇:容器监控cAdvisor原理分析


下一篇:紫色飞猪的研发之旅(十)-容器平台工作负载的扩缩容/启/停/重启开发