在Golang中读取非常大的文件

我目前正在尝试读取具有200多个列和1000多个行的文件。 我使用以下代码:</ p>

  var结果[] string 

file,err:= os.Open(“ t8.txt”)
if(err!= nil ){
fmt.Println(err)
}
defer file.Close()
scan:= bufio.NewScanner(file)
for scan.Scan(){
结果= append(结果,scan.Text( ))

}

fmt.Println(scan.Err())//令牌太长
</ code> </ pre>

但是当我打印出 结果,我得到的只是第一行,因为它说令牌太长。 当我在较小的文件上尝试时,它可以正常工作。 Golang中有什么方法可以扫描大文件? </ p>
</ div>

展开原文

原文

I'm currently trying to read in a file with 200+ columns and 1000+ rows. I use the following code:

var result []string

file, err := os.Open("t8.txt")
if (err != nil) {
  fmt.Println(err)
}
defer file.Close()
scan := bufio.NewScanner(file)
for scan.Scan() {
  result = append(result, scan.Text())

}


fmt.Println(scan.Err()) //token too long

However when I print out the results, all I get is the first line because it says the token is too long. When I try it on smaller files, it works fine. Is there a way in Golang that I could scan in large files?

duanmengmiezen8855
duanmengmiezen8855 是的,constbufio.MaxScanTokenSize=64*1024。因此,您要么需要使用较小的标记(例如,使用拆分功能对列进行标记),要么使用其他读取方法。顺便说一句,您是否想要/需要将全部内容存储在内存中,还是只是按行进行处理?
5 年多之前 回复
doushou9028
doushou9028 无论如何,当我想读取整个文件时,有时只使用syscall.Mmap,就像这里一样。
5 年多之前 回复
dongpan1871
dongpan1871 我也不知道他们也有scan.Err(),但是现在我看到它返回“令牌时间太长”。
5 年多之前 回复
dpecb06062
dpecb06062 永远不要忽略错误返回值!(两者均来自os.Open,并在循环后检查scan.Err())。
5 年多之前 回复

1个回答



正如@Dave C在注释中指出的那样,您正在运行的MaxScanTokenSize = 64 * 1024 </ p>

要解决此限制,请使用bufio.Reader,它具有一个ReadString(delim byte)方法,该方法似乎适合您的情况。</ p>

从Scanner中转到doc(特别是最后一句话) ):</ p>


扫描仪提供了一个方便的界面,用于读取数据,例如用换行符分隔的文本行的
文件。 连续调用Scan
方法将逐步浏览文件的“令牌”,而跳过令牌之间的字节
。 令牌的规范由类型为SplitFunc的split
函数定义; 默认的split函数将
输入拆分为带有终止行的行。

在此软件包中定义了分割函数,用于将文件扫描为行,字节,
UTF-8编码的符文和空格分隔的单词。 客户端可以改为提供自定义拆分功能。</ p>

扫描在EOF,第一个I / O错误或令牌太大而无法容纳在缓冲区中时无法停止。 扫描停止时,读取器可能已任意提前了最后一个令牌。 需要对错误处理或大令牌进行更多控制的程序,或者必须在读取器上运行顺序扫描的程序,应改用bufio.Reader。</ p>
</ blockquote>
</ div>

展开原文

原文

As already pointed out by @Dave C in the comments you are running into MaxScanTokenSize = 64 * 1024

To get around that limitation, use bufio.Reader which has a ReadString(delim byte) method which seems appropriate for your case.

From the Scanner go doc (specifically the last sentence):

Scanner provides a convenient interface for reading data such as a file of newline-delimited lines of text. Successive calls to the Scan method will step through the 'tokens' of a file, skipping the bytes between the tokens. The specification of a token is defined by a split function of type SplitFunc; the default split function breaks the input into lines with line termination stripped. Split functions are defined in this package for scanning a file into lines, bytes, UTF-8-encoded runes, and space-delimited words. The client may instead provide a custom split function.

Scanning stops unrecoverably at EOF, the first I/O error, or a token too large to fit in the buffer. When a scan stops, the reader may have advanced arbitrarily far past the last token. Programs that need more control over error handling or large tokens, or must run sequential scans on a reader, should use bufio.Reader instead.

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问