golang 如何识别文本格式(golang读取txt文件一次读取一行)

技术Golang怎么读取单行超长的文本这篇文章主要介绍“Golang怎么读取单行超长的文本”,在日常操作中,相信很多人在Golang怎么读取单行超长的文本问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望

这篇文章主要介绍”戈朗怎么读取单行超长的文本”,在日常操作中,相信很多人在Golang怎么读取单行超长的文本问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”戈朗怎么读取单行超长的文本”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1.问题复现

首先注释主要的函数里面的内容,执行CreateBigText函数,它会创建一个含有3行内容的文件,第一行是一个长度超过100KB的行。然后解决主要的函数的注释,尝试执行代码,会发现只有一行错误信息:

Golang怎么读取单行超长的文本

packagemain

导入(

布菲奥

字节数

日志

操作系统

‘ strconv ‘

)

func main(){ 0

文件,err:=os .打开(‘。/read/test.txt ‘)

伊弗。=零

日志。致命的

}

ReadBigText(文件)

}

funcReadBigText(文件*os .文件){ 0

延期文件。关闭()

scanner:=bufio .新闻扫描器(文件)

佛斯坎纳。扫描(){ 0

println(扫描仪文本())

}

//输出错误

println(扫描仪Err().错误())

}

funcreateBigtext(){ 0

文件,err:=os .创建(‘。/read/test.txt ‘)

伊弗。=零

日志。致命的

}

延期文件。关闭()

数据:=make([]字节,0,32*1024)

buffer:=字节。纽博弗(数据)

//构造一个大的单行数据

对于I :=0;i50000我

缓冲区WriteString(strconv .Itoa(i))

}

//写入一个换行符

缓冲区。写字节(‘ \n ‘)

缓冲区.写字符串(‘ Iloveyou昨天和今天!\ n’)

缓冲区. WriteString(“)有一美人兮,见之不忘\ \ n’)

//将3行写入文件

文件。写(缓冲区。字节())

日志Println(‘创建文件成功)

}

2.问题探究

让我们来探究一下这个问题的原因,首先看一下扫描()方法的注释,这个方法就是每次扫描到下一个令牌,然后就可以通过获取字节或者文本的方法来获取扫描过的令牌。如果它返回值是假的,就会返回扫描期间遇到的错误,除了io。文件结束

扫描将扫描器前进到下一个令牌,然后通过字节或文本方法可以使用该令牌。当扫描停止时,它返回假的,要么到达输入的末尾,要么出现错误。在扫描返回错误的后呃,方法将返回扫描过程中发生的任何错误,除非是超正析象管错误电渗流,误差将返回零。如果使分离函数返回太多空标记而不推进输入,扫描就会死机。这是扫描仪常见的错误模式。

rong>所以Scan()和Text()函数是这样结合起来使用的,首先Scan()会扫描出一个token,然后Text()将其转成文本(或者其它方法转成字节),循环执行这种操作就可以按行读取一个文件。

通过阅读Scan()函数的源码,我们可以发现这样一个判断,如果buf的长度大于了最大token长度,那就会报错,见下图。

Golang怎么读取单行超长的文本

继续查找,可以看到最大长度已经定义好了,它的长度是 64*1024 byte,即64KB,所以一行文本超过了这个最大长度,那么就会报错!

Golang怎么读取单行超长的文本

3.问题解决

其实大部分情况下我们都应该使用Scan()函数结合Text()或者Bytes()函数来读取文件的,这个也是官方推荐的,因为它们是 high-level 方法,用起来很方便。但是如果我们有一些极端的情况,例如单行超过64KB,那么怎么办呢?(这种情况是很少的,但是又有可能会遇到这种需求的,例如文件里面存储了一串Base64编码)

这里可以这样来使用,这个方法不会受到64KB的限制,ReaderString方法会按照指定的定界符来读取一个完整的行,返回值是字符串和读取遇到的错误。如果想要读取返回值为字节的话,可以使用 ReadBytes 方法。

func ReadBigText(file *os.File) {
	defer file.Close()
	reader := bufio.NewReader(file)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%d %s", len(line), line)
	}
}

Golang怎么读取单行超长的文本

通过阅读源码可知,其实这个方法也是会遇到行太长的问题,只不过它忽略了这种情况。

ErrBufferFull就是这个缓冲区溢出错误。

Golang怎么读取单行超长的文本

我们继续进入内容其实也可以知道,它默认的缓冲区大小是4KB。

Golang怎么读取单行超长的文本

4.扩展

上面都说相对高层的方法,我们来看一下相对底层的方法。

ReadLine is a low-level line-reading primitive. Most callers should use ReadBytes('\n') or ReadString('\n') instead or use a Scanner.

ReadLine是读取一行,但是它是一个 low-level 方法,它会返回三个值:[]byte、isPrefix bool和err error。
其中最令人好奇的是第二个参数,它如果是true,则表示当前行没有读取完毕,但是缓冲区满了,可以看下面这段注释。

If the line was too long for the buffer then isPrefix is set and the beginning of the line is returned. The rest of the line will be returned from future calls.

func ReadBigText(file *os.File) {
	defer file.Close()
	reader := bufio.NewReader(file)

	for {
		bline, isPrefix, err := reader.ReadLine()
		if err == io.EOF {
			break // 读取到文件结束才退出
		}
		// 读取到超长行,即单行超过4k字节,直接写入文件,不对此行做处理
		if isPrefix {
			fmt.Print(string(bline))
			continue
		}

		fmt.Println(string(bline))
	}
}

Golang怎么读取单行超长的文本

不过需要注意这个方法读取出来的数据是不包括换行符的,所以我是用的println打印输出的。

如果你也去看了 ReadStringReadBytesReadLine 方法,会发现两种都依赖于一个底层的方法——ReadSlice方法。这个方法很原始,一般不会直接使用它。如果它遇到了超长行,它就会直接返回读取到的字节和一个ErrBufferFull,那这样我们就可以根据这个错误来继续读取数据了。这种方式还是相对麻烦了一些,不过如果你可以理解的话,对于上面的方法也就不是问题了。学习嘛,还是有必要一探究竟的。不过阅读源码感觉有些还是理解起来很困难,特别是这些英语注释,不过也能看一个七七八八了。还不行的话,那就再借助一些翻译软件,不过我个人觉得提高自己的英语能力还是非常必要的。

func ReadBigText(file *os.File) {
	defer file.Close()
	reader := bufio.NewReader(file)
	for {
		byt, err := reader.ReadSlice('\n')
		if err != nil {
			if err == bufio.ErrBufferFull {
				fmt.Print(string(byt))
				continue
			}
			log.Fatal(err)
		}
		fmt.Print(string(byt))
	}
}

Golang怎么读取单行超长的文本

到此,关于“Golang怎么读取单行超长的文本”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/155206.html

(0)

相关推荐

  • 如何防止人为误操作MySQL数据库

    技术如何防止人为误操作MySQL数据库这篇文章主要介绍“如何防止人为误操作MySQL数据库”,在日常操作中,相信很多人在如何防止人为误操作MySQL数据库问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望

    攻略 2021年10月23日
  • 图书馆英语怎么写,“图书馆”用英语怎么说

    技术图书馆英语怎么写,“图书馆”用英语怎么说在图书馆用英语翻译过来是in the library.in表地点时图书馆英语怎么写,指在某一立体空间范围内。library的英式读法是[laɪbrəri];美式读法是[laɪb

    生活 2021年10月22日
  • 1公斤水等于多少升水,100升水等于多少公斤水

    技术1公斤水等于多少升水,100升水等于多少公斤水一百升水等于200斤1公斤水等于多少升水。 1升水就是1公斤,所以100升水就是100公斤,1公斤等于两斤,所以100升水就是200斤。 千克是公制计量单位,一千克等于一

    生活 2021年10月25日
  • 二分图

    技术二分图 二分图二分图
    定义
    二分图,又称二部图,英文名叫 Bipartite graph。
    二分图是什么节点由两个集合组成,且两个集合内部没有边的图。
    换言之,存在一种方案,将节点划分成满足以上性质

    礼包 2021年11月24日
  • 对镜贴花黄通假字,当窗理云鬓对镜贴花黄描述的是谁

    技术对镜贴花黄通假字,当窗理云鬓对镜贴花黄描述的是谁当窗理云鬓对镜贴花黄描述的是花木兰对镜贴花黄通假字。意思是当着窗子整理像乌云一样柔美的头发,对着镜子在额上贴好花黄。
    《木兰诗》是一首北朝民歌,宋郭茂倩《乐府诗集》归入

    生活 2021年10月30日
  • 抖音刷评价平台,抖音免费刷点赞神器

    技术抖音刷评价平台,抖音免费刷点赞神器抖音刷评价平台,抖音免费刷点赞神器
    抖音免费刷赞手机版
    第四个就是播放完整度。播放完整度说白了就是人们打开你这个视频之后,能否看得完,是打开看了两三秒就换下一个,还是耐着性子从头看

    测评 2021年11月13日