go语言读取文件的基本流程

最近本人在做一个开源项目 虽然是go语言新手 还是浅浅记录一下

目录

1.首先是使用 os.Open 函数打开文件

2.使用 os.Stat 函数获取文件的状态信息并判断是否有错

3.文件读取

3.1按块读取

3.2按行读取

4.close


首先源码奉上
 

func fileIsRDB(aofFilepath string) bool {
	fp, err := os.Open(aofFilepath)
	if err != nil {
		fmt.Printf("Cannot open file %s:%s\n", aofFilepath, err.Error())
		os.Exit(1)
	}
	sb, err := os.Stat(aofFilepath)
	if err != nil {
		fmt.Printf("cannot stat file: %s\n", aofFilepath)
		os.Exit(1)
	}
	size := sb.Size()
	if size == 0 {
		fp.Close()
		return false
	}
	if size >= 8 {
		sig := make([]byte, 5)
		_, err := fp.Read(sig)
		if err == nil && string(sig) == "REDIS" {
			fp.Close()
			return true
		}
	}
	fp.Close()
	return false
}

1.首先是使用 os.Open 函数打开文件

将返回的文件指针 fp 以及可能出现的错误存储在变量中。

func Open(name string) (*File, error)
	fp, err := os.Open(aofFilepath)
	if err != nil {
		fmt.Printf("Cannot open file %s:%s\n", aofFilepath, err.Error())
		os.Exit(1)
	}

如上图所示,我们使用 os.Open 函数打开了一个名为 aofFilepath的文件。如果打开文件时发生错误,我们会在错误处理代码块中打印错误信息并返回。

	fp.Close()
	return false

和c语言一样在读取完毕的时候需要close以避免资源泄露,除了以上在return上面加fp.close()还可以用go语言使用defer关键字确保函数返回之前关闭文件。

2.使用 os.Stat 函数获取文件的状态信息并判断是否有错

将返回的信息存储在变量 sb

func Stat(name string) (FileInfo, error)

name表示文件路径

FileInfo是一个接口 FileInfo 对象用来获取文件的相关属性和信息

	sb, err := os.Stat(aofFilepath)
	if err != nil {
		fmt.Printf("cannot stat file: %s\n", aofFilepath)
		os.Exit(1)
	}
	size := sb.Size()
	if size == 0 {
		fp.Close()
		return false
	}
	if size >= 8 {
		sig := make([]byte, 5)
		_, err := fp.Read(sig)
		if err == nil && string(sig) == "REDIS" {
			fp.Close()
			return true
		}
	}
        fp.Close()
        return false

如上图所示 这里我只需要检查文件是否为空,而不需要获取详细的文件信息,所以就os.stat后,调用返回回来的sb的size,如果size==0则说明文件为空,返回错误。

FileInfo接口提供了许多用于检索文件信息的方法,例如 Name,size,ISdir 等等。可以根据实际需要选择相应的方法来获取文件的属性和特征。

如下图

fmt.Println("File Name:", fileInfo.Name())
	fmt.Println("File Size:", fileInfo.Size())
	fmt.Println("File Mode:", fileInfo.Mode())
	fmt.Println("Is Directory:", fileInfo.IsDir())
	fmt.Println("Last Modified:", fileInfo.ModTime())

3.文件读取

这里介绍两种常见的读取方式 按块读取和按行读取

3.1按块读取

sig := make([]byte, 5)
for{
		_, err := fp.Read(sig)
           if err == io.EOF {
				fp.close()
                return false}
		   if err == nil && string(sig) == "REDIS" {
			    fp.Close()
			    return true}
}
func (f *File) Read(b []byte) (n int, err error)

首先创建根据实际情况创建长度 的字节切片 sig。

每次使用 fp.Read(sig) 从文件中读取 5 个字节的数据,并将实际读取的字节数和可能出现的错误存储在变量中。直到找到REDIS退出或者文件末尾退出。

3.2按行读取

	reader := bufio.NewReader(fp)
	for {
		lines, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			} else {
				fmt.Printf("cannot read file: %s\n", aofFilepath)
				os.Exit(1)
			}
		}
		if lines[0] == '#' {
			continue
		} else if lines[:4] == "file" {
			is_manifest = true
		}
	}
	fp.Close()
	return is_manifest

首先创建一个bufio.NewReader(fp) 对象,它用于从文件指针 fp 中读取数据。

创建 bufio.NewReader(fp) 对象是为了提高文件读取的效率。

用文件指针 fp 进行读取操作。缓冲读取器会自动将读取的内容存储在内部的缓冲区中,并提供诸如 ReadStringReadLine 等方法来更方便地读取文件内容。

这样的好处是它会预先读取更多的数据到缓冲区中,当你通过 ReadString 等方法读取数据时,实际上是直接从缓冲区中获取数据,而不需要每次都触发系统调用。

注意我这里调用了缓存区 要注意缓存区也有大小限制 超过缓存区大小则不会读取 如果是太大的文件很可能读不到自己想要的内容

	lines, err := reader.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				break
			} else {
				fmt.Printf("cannot read file: %s\n", aofFilepath)
				os.Exit(1)
			}
		}

在无限循环内部,使用 reader.ReadString('\n') 读取文件中的一行数据,并将其存储在 lines 变量中。之所以它可以读取文件中的一行数据是因为reader.ReadString('\n') 会从缓冲读取器中读取字符,直到遇到 \n(换行符)为止。

4.close

刚才说了和c语言一样在读取完毕的时候需要close以避免资源泄露,除了以上在return上面加fp.close()还可以用go语言使用defer关键字确保函数返回之前关闭文件。

其他知识

 else if lines[:4] == "file" {
			is_manifest = true
}

判断前面字符串是否为特定字符串可以用切片的这种方式

或者

else if strings.HasPrefix(line, "file") {
    is_manifest = true
}

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值