golang 写文件的几种方法 (临时文件)

一、写文件

写文件一般步骤

  1. 打开文件,获取文件句柄
  2. 根据不同方法,将数据写入
  3. 关闭文件句柄


打开文件,获取文件句柄

os.OpenFile(path, os.O_CREATE, 0666)

我们来了解一下第二个参数的含义:

O_RDONLY    // 只读模式打开文件
O_WRONLY   // 只写模式打开文件
O_RDWR     // 读写模式打开文件
O_APPEND    // 写操作时将数据附加到文件尾部
O_CREATE    // 如果不存在将创建一个新文件
O_EXCL      // 和O_CREATE配合使用,文件必须不存在
O_SYNC     // 打开文件用于同步I/O
O_TRUNC     // 如果可能,打开时清空文件



第三个参数代表使用指定的模式打开文件

根据不同方法,将数据写入

1. 使用os.File来写文件

三个方法:

  1. func (f *File) Write(b []byte) (n int, err error)
    Write向文件中写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。

  2. func (f *File) WriteString(s string) (ret int, err error)
    WriteString类似Write,但接受一个字符串参数。

  3. func (f *File) WriteAt(b []byte, off int64) (n int, err error)
    WriteAt在指定的位置(相对于文件开始位置)写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。

// 写个函数,确保文件夹存在,省的重复写
func ensureDirExist(path string) error {
	dir := filepath.Dir(path)
	exists := isPathExists(dir)
	if !exists {
		err := os.MkdirAll(dir, os.ModePerm)
		if err != nil {
			return err
		}
	}
	return nil 
}
// 判断路径是否存在
func isPathExists(path string) bool {
	if _, err := os.Stat(path); err != nil {
		return false
	}
	return true
}
// 将字符串写入文件
func writeFileWithOsFile(str, path string) error {
	// 先验证文件夹是否存在
	err := ensureDirExist(path)
	if err != nil {
		return err
	}
	// 若文件夹不存在,会出错
	f, err := os.OpenFile(path, os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
	defer f.Close()

	_, err = f.Write([]byte(str))
	if err != nil {
		return err
	}
	_, err = f.WriteString(str)
	if err != nil {
		return err
	}
	// 获取文件相关信息
	fileInfo, err := f.Stat()
	if err != nil {
		return err
	}

	fmt.Println(fileInfo.Size())
	_, err = f.WriteAt([]byte(str), fileInfo.Size())

	fmt.Println(fileInfo.Size()) // 注意:得到的fileInfo不会更新
	return err
}

2.使用bufio来写文件

带缓冲的I/O。主要应用场景(大量的写入,多次进行I/O操作,很耗性能),例如:服务器接收数据,客户端发过来的数据比较少,就几个字节这种。会有很多这种操作,若一直写,会很慢。

func writeFileWithBufio(str, path string) error {
	// 先验证文件夹是否存在
	err := ensureDirExist(path)
	if err != nil {
		return err
	}
	// 若文件夹不存在,会出错
	f, err := os.OpenFile(path, os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
	defer f.Close()

	writer := bufio.NewWriterSize(f, 1024)
	_, err = writer.Write([]byte(str))
	if err != nil {
		return err
	}
	_, err = writer.WriteString(str)
	if err != nil {
		return err
	}
	//err = writer.Flush()
	fmt.Println(writer.Size())

	return err

}

3.使用ioutil来写

func writeFileWithIoutil(str, path string) error {
	err := ensureDirExist(path)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(path, []byte(str), os.ModePerm)
}

ioutil 这个帮助类还挺好用的,可以自己再看看。
例如:创建临时文件

func CreateTempFile() {
	buf := "Hello, World"
	//在dir目录下创建一个新的、使用prefix为前缀的临时文件,以读写模式打开该文件并返回os.File指针。如果dir是空字符串,TempFile使用默认用于临时文件的目录(参见os.TempDir函数)。不同程序同时调用该函数会创建不同的临时文件,调用本函数的程序有责任在不需要临时文件时摧毁它。
	file, err := ioutil.TempFile("", "tmpfile")
	if err != nil {
		panic(err)
	}
	defer func() {
		file.Close()
		// 一般来说,临时文件不用了,需要移除
		err := os.Remove(file.Name())
		if err != nil {
			log.Fatal(err.Error())
		}
	}()

	if _, err := file.Write([]byte(buf)); err != nil {
		panic(err)
	}

	fmt.Println(file.Name()) // C:\Users\aaa\AppData\Local\Temp\tmpfile741822103
}

4.使用io包中的WriteString方法

func writeFileWithIo(str, path string) error {
	// 先验证文件夹是否存在
	err := ensureDirExist(path)
	if err != nil {
		return err
	}
	// 若文件夹不存在,会出错
	f, err := os.OpenFile(path, os.O_APPEND | os.O_CREATE | os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
	defer f.Close()
	_, err = io.WriteString(f, str)
	return err
}

关闭文件句柄

使用完之后,需要将文件关闭,一般在defer中处理

f, err := os.Open("F:/a.txt")
if err != nil {
	log.Fatal(err)
	return 
}
defer f.Close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值