Go The Way 之文件操作

读取文件

读取大文本

/**
适用场景: 要读取的文件比较大
 */
func testReadBigDataFromFile()  {
	file, err := os.Open("F:/goworkspace/src/goStudy/file/1.txt")
	if err != nil {
		fmt.Println(err)
		return
	}
	defer file.Close()
	// 读取
	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('\n')
		if err == io.EOF {
			//已经到达文件的末尾
			break
		}
		fmt.Println(str)
	}
}
  • 例子适用于大文本文件,主要使用了 bufio.NewReader(file) 缓存区,能够加速获取数据
  • os.Open(filePath) 打开一个存在的文件
  • 成功打开文件后,记住要关闭:defer file.Close()
  • reader.ReadString(’\n’) 以换行符为分割符从缓冲区中获取数据
  • err == io.EOF 判断是否到达文件的末尾,如果遍历到文件的末尾会抛出io.EOF 错误

读取小文本

/**
应用场景: 读取数据量小的文件
 */
func testReadAllDataFromFile() {
	filePath := "F:/goworkspace/src/goStudy/file/1.txt"
	arr, err := ioutil.ReadFile(filePath)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(arr))
}
  • ioutil.ReadFile(filePath) 直接从文件中获取所有的数据,返回[]byte

写文件

  • 文档: 前往

  • func OpenFile(name string, flag int, perm FileMode) (file *File, err error)

    • os.OpenFile 是一个更一般行的文件打开函数。
    • name 文件名,
    • 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  // 如果可能,打开时清空文件
)
  • perm 权限控制(仅适用于linux、unix、MACOS 等,不适合Windows)例如 0666等

向一个不存在的文件中,写入五行 hello world

func testWriteToNoExistFile() {
	filePath := "F:/goworkspace/src/goStudy/file/2.txt"
	file, err := os.OpenFile(filePath,  os.O_CREATE | os.O_WRONLY , 0666)
	if err != nil {
		log.Fatal("打开文件出错》", err)
	}

	// 关闭文件
	defer file.Close()

	writer := bufio.NewWriter(file)
	str := "hello world !\n"
	for i:=0; i<5; i++  {
		writer.WriteString(str)
	}
	//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
	// 否则文件中不会有数据
	writer.Flush()

}
  • bufio.NewWriter(file) 获取一个写的缓冲区,加速写的速度
  • writer.WriteString(str) 将字符串写到缓存区中
  • writer.Flush() 将缓存区中的数据刷新到文件中,这样文件才有内容,如果不执行该函数,文件就没有内容

向一个已经存在的文件中,替换文件中内容

func testWriteToExistFile() {
	filePath := "F:/goworkspace/src/goStudy/file/2.txt"
	file, err := os.OpenFile(filePath,  os.O_WRONLY | os.O_TRUNC , 0666)
	if err != nil {
		log.Fatal("打开文件出错》", err)
	}

	// 关闭文件
	defer file.Close()

	writer := bufio.NewWriter(file)
	str := "你好,世界\n"
	for i:=0; i<5; i++  {
		writer.WriteString(str)
	}
	//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
	// 否则文件中不会有数据
	writer.Flush()

}

向一个已经存在的文件中,替换文件中内容

// 向一个已经存在的文件中,替换文件中内容
func testAppendWriteToExistFile() {
	filePath := "F:/goworkspace/src/goStudy/file/2.txt"
	file, err := os.OpenFile(filePath,  os.O_WRONLY | os.O_APPEND , 0666)
	if err != nil {
		log.Fatal("打开文件出错》", err)
	}

	// 关闭文件
	defer file.Close()

	writer := bufio.NewWriter(file)
	str := "hello world\n"
	for i:=0; i<5; i++  {
		writer.WriteString(str)
	}
	//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
	// 否则文件中不会有数据
	writer.Flush()

}

先读取文件内容,后追加写入数据

func testReadFileThenAppendWriteToExistFile() {
	filePath := "F:/goworkspace/src/goStudy/file/2.txt"
	file, err := os.OpenFile(filePath,  os.O_RDWR | os.O_APPEND , 0666)
	if err != nil {
		log.Fatal("打开文件出错》", err)
	}

	// 关闭文件
	defer file.Close()

	//读取数据
	reader := bufio.NewReader(file)
	for {
		str, er := reader.ReadString('\n')
		if er == io.EOF {
			fmt.Println("文件已到末尾 》", er)
			break
		}
		fmt.Println(str)

	}

	// 开始写入数据
	writer := bufio.NewWriter(file)
	str := "再次追加\n"
	for i:=0; i<5; i++  {
		writer.WriteString(str)
	}
	//因为writer 是带缓存的,因此在使用WriteString 函数时,其实内存先写入缓存中,所以如果需要将数据保存到磁盘需要调用 Flush() 进行刷新,
	// 否则文件中不会有数据
	writer.Flush()

}

拷贝文件

/**
文件拷贝 :
可以使用到 io 包下的Copy函数
func Copy(dst Writer, src Reader) (written int64, err error)
  */
func testCopyFile(fromFile string, toFile string) (written int64, err error) {
	fileFrom,err := os.Open(fromFile)
	if err != nil {
		fmt.Println("文件打开失败",err)
		return 0, err
	}
	defer fileFrom.Close()
	reader := bufio.NewReader(fileFrom)

	fileTo,err := os.OpenFile(toFile, os.O_CREATE | os.O_WRONLY , 0666)
	if err != nil {
		fmt.Println("文件打开失败",err)
		return 0, err
	}

	defer fileTo.Close()

	writer := bufio.NewWriter(fileTo)
	defer writer.Flush() // 这里必须要有,因为博主在第一次执行的时候发现文件有了,但是文件中的内容没有,虽然输出拷贝成功。 查看Copy函数的源码发现没有使用Flush() 函数。
	//所以我们在拷贝完成后需要自己手动刷新一下。
	return io.Copy(writer, reader)
}

  • 使用到的函数 func Copy(dst Writer, src Reader) (written int64, err error)
  • 文档地址:前往
  • 先打开一个存在的文件获取输入流,然后打开一个不存在的文件(以新建,只写的方式)获取输出流。然后调用os.Copy() 函数进行拷贝
  • 别忘记了只写刷新语句,不然拷贝后的文件没有内容,只有空文件
  • 测试一下:
package main

import (
	"os"
	"fmt"
	"bufio"
	"io"
	"io/ioutil"
	"log"
)

func main()  {
	fromFilePath := "F:/goworkspace/src/goStudy/file/2.txt"
	toFilePath := "F:/goworkspace/src/goStudy/file/3.txt"
	_,  err := testCopyFile(fromFilePath, toFilePath)
	if err != nil {
		fmt.Println("拷贝出错》", err)
	} else {
		fmt.Println("拷贝成功")
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值