Golang 按行读取文件的 3 种方法

这篇具有很好参考价值的文章主要介绍了Golang 按行读取文件的 3 种方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Golang 是一种现代的编程语言,它具有高效、简洁和可扩展等特点,因此在各种领域广泛应用。在 Golang 中,读取文件是一个常见的操作。在本篇技术博客中,我将介绍如何在 Golang 中按行读取文件。

1.bufio.Scanner

Golang 中有一个 bufio 包,它提供了 Scanner 类型,可以方便地按行读取文件。我们可以使用 Scanner 的 Scan() 方法来读取每一行。

bufio.Scanner是一个基于缓冲区的数据扫描器,它提供了方便的逐行/逐词读取操作。Scan 方法是bufio.Scanner 的一个核心方法,用于扫描缓冲区中的数据并返回扫描到的下一个 Token。

Scan 方法的签名如下:

func (s *Scanner) Scan() bool

该方法返回一个 bool 类型值,表示扫描是否成功。如果扫描成功,该方法会将下一个Token读取出来并保存在Scanner的Text字段中。如果扫描失败,则返回false。

在读取Token之前,Scanner会将缓冲区中的数据读取到底层的Reader中,并从底层的Reader中获取新的数据填充到缓冲区中。因此,在Scan方法调用之前,Scanner的缓冲区中可能已经包含了一部分数据,也可能为空。

扫描过程中,Scanner会将缓冲区中的数据按照分隔符进行分割,并将分割后的Token返回。默认情况下,Scanner使用换行符作为分隔符,即每次扫描一行数据。如果需要使用其他分隔符,可以使用Scanner的Split方法进行设置。

// ReadLines reads all lines of the file.
func ReadLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var lines []string
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

上面的代码中,我们首先使用 NewScanner() 函数创建一个 Scanner 对象。然后在 for 循环中,我们使用 Scanner 的 Scan() 方法读取文件的每一行,然后使用 Text() 方法获取每一行的内容。最后,我们将获取到的行追加到字符串切片中。

2.bufio.Reader

除了使用 Scanner 类型之外,我们还可以使用 bufio 包中的 Reader 类型按行读取文件。在使用 bufio.Reader 时,我们需要使用 ReadBytes() 或 ReadString() 方法来读取每一行,示例代码如下:

// ReadLinesV2 reads all lines of the file.
func ReadLinesV2(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	var lines []string
	reader := bufio.NewReader(file)
	for {
		// ReadString reads until the first occurrence of delim in the input,
		// returning a string containing the data up to and including the delimiter.
		line, err := reader.ReadString('\n')
		if err == io.EOF {
			lines = append(lines, line)
			break
		}
		if err != nil {
			return lines, err
		}
		lines = append(lines, line[:len(line)-1])
	}
	return lines, nil
}

上面的代码中,我们使用 NewReader() 函数创建一个 Reader 对象。在 for 循环中,我们使用 ReadString() 函数读取每一行的内容,并将其追加到字符串切片中。

需要注意的是,在使用 ReadString() 函数时,我们需要指定分隔符,例如 ‘\n’ 表示以换行符为分隔符。如果读取的文件中没有指定的分隔符,ReadString() 函数会返回一个错误,因此我们需要在 for 循环中检查是否发生了错误。

3.bufio.Reader 的 ReadLine

使用 bufio.Reader 逐行读取文件时,除了使用 ReadBytes() 或 ReadString() 方法,还可以使用 ReadLine() 函数。

// ReadLinesV3 reads all lines of the file.
func ReadLinesV3(path string) ([]string, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	var lines []string
	r := bufio.NewReader(f)
	for {
		// ReadLine is a low-level line-reading primitive.
		// Most callers should use ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
		bytes, _, err := r.ReadLine()
		if err == io.EOF {
			break
		}
		if err != nil {
			return lines, err
		}
		lines = append(lines, string(bytes))
	}
	return lines, nil
}

使用 bufio.Reader 的 ReadLine() 方法可以读取一行数据,但是需要注意它的返回值。ReadLine() 函数的返回值包括三个部分:读取到的数据、是否读取完整一行以及错误信息。如果读取到的数据超出了缓存区的大小,它会返回一个错误信息,而不是完整的一行数据。

因此,如果读取的一行数据的长度超过了缓存区的大小,ReadLine() 函数将无法读取到完整的一行数据。为了避免这种情况的发生,我们可以通过设置缓存区的大小来解决。

ReadLine 是一个低级的行读取原语。大多数调用者应该使用 ReadBytes(‘\n’) 或 ReadString(‘\n’),或者使用 Scanner。

4.dablelv/cyan

本文实现的函数已放置开源仓库 dablelv/cyan,欢迎大家使用。

package main

import (
	"github.com/dablelv/go-huge-util/file"
)

func main() {
	path := "your/file/path"
	lines, err := file.ReadLines(path)
	lines, err = file.ReadLinesV2(path)
	lines, err = file.ReadLinesV3(path)
}

推荐使用 file.ReadLines。

dablelv/cyan 除了类型转换,还有很多其他实用函数,如加解密、zip 解压缩等,欢迎大家使用、Star、Issue 和 Pull Request。


参考文献

dablelv/cyan - GitHub文章来源地址https://www.toymoban.com/news/detail-706067.html

到了这里,关于Golang 按行读取文件的 3 种方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Golang中读写CSV文件的全面指南

    CSV(逗号分隔值)文件是一种常见的数据存储格式,广泛应用于数据导入、导出、分析和交换等场景。在Golang中,有许多库和工具可以帮助我们读取和写入CSV文件,使数据处理变得简单而高效。本文将深入探讨如何在Golang中使用标准库以及第三方库来读写CSV文件。 Golang的标准

    2024年02月03日
    浏览(36)
  • golang读取yaml文件

    yaml文件名:agent.yml 注意,空格,不要用tab键 golang文件:main.go 执行:

    2024年02月09日
    浏览(37)
  • Golang:文件读写操作WriteFile、ReadFile和0644权限

    方法签名 示例代码 关于 0644 权限,可以参考下图 第0位:文件属性。“-” 表示普通文件;“d” 表示是一个目录 第1~3位:文件所有者的权限 第4~6位:文件所属用户组的权限 第7~9位:其他人的权限 参考 Go写文件的权限 WriteFile(filename, data, 0644)? Golang 基础之文件操作

    2024年04月28日
    浏览(29)
  • Golang - go build打包文件

    Go编译打包文件 1、简单打包 程序 main1.go: 打包: # 在linux服务上执行下面的3个命令 执行: 2、打包时为程序中的变量设置值 程序 main2.go : 打包:打包方式和上面一样,这里只介绍linux下的打包。 # 在linux服务上执行下面的命令 执行: 3、打包时指定名称 执行: go build的时

    2024年02月09日
    浏览(39)
  • golang gRPC:根据.protobuf文件生成go代码

    安装 protoc 编译器。如果没有安装,可以参考官方文档进行安装。 使用 protoc 命令生成 gRPC 代码: 此命令将生成 .pb.go 和 _grpc.pb.go 文件,其中包含 protobuf 和 gRPC 的代码实现. –go_out选项会生成纯粹的Protocol Buffer消息代码,这包括Go语言的消息结构体和一些辅助方法。如果你只

    2024年02月14日
    浏览(42)
  • go 笔记 第七章 golang 的函数 func 方法

    声明函数 func 函数名(入参1 类型, 入参2 类型,… )(出参1 类型, 出参2 类型…){ 函数体,写逻辑 出参一定要全部 return, return 出参 } 函数内部不可以声明带名字的函数,可以声明匿名函数和自执行函数 函数名大写可以被其他包调用,小写私有,变量名也是一样 return 后面可以不

    2024年02月15日
    浏览(42)
  • 【Golang】解决Go test执行单个测试文件提示未定义问题

    目录 背景 根本原因 解决方法 解决 多级引用或多个引用包的情况 总结  资料获取方法 很多人记录过怎么执行Go test单个文件或者单个函数,但是要么对执行单文件用例存在函数或变量引用的场景避而不谈,要么提示调用了其它文件中的模块会报错。其实了解了go test命令的机

    2024年02月14日
    浏览(38)
  • java 逐行读取文件(读取文件每一行、按行读取文件)附带示例代码

    最快的读取每一行 相比较Scanner慢一点 行数达到一定规模,使用此方法读取会非常慢 一次把所有数据都读到内存中,当文件非常大时,会消耗掉内存资源导致程序崩掉,文件规模小推荐使用 统计每一行日志ip出现的次数

    2024年02月11日
    浏览(47)
  • Java 按行读取写入文件

    目录 一、按行读取 二、按行写入 这里采用java.nio.file.Files:readAllLines方法,参见JDK8 API官方文档 Java Platform SE 8  具体实现Demo: 这里采用FileWriter与BufferWriter方法 FileWriter: 用于写入字符流。对于写入原始字节的流,可以考虑使用FileOutputStream。 BufferWriter:  将文本写入字符输出流

    2024年02月15日
    浏览(43)
  • java中按行读取文件内容

          java中按行来读取文件内容,一般对文件也是又要求的,比如文件编码utf-8,内容是按行可读,而不是一堆字节码。这类文件,我们按行读取,主要是方便快速查看内容,并且用这些内容来作别的用途,这类文件内容不宜过多,否则加载容易出现意想不到的问题,比如内

    2024年02月03日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包