Go 传递指向bufio.Scanner()的指针
我的目标是在多个goroutine之间共享一个内存映射文件。每个goroutine都需要逐行迭代文件,因此我希望先将完整内容存储在内存中,以加快速度 我尝试的方法是将指针传递给Go 传递指向bufio.Scanner()的指针,go,concurrency,memory-mapped-files,Go,Concurrency,Memory Mapped Files,我的目标是在多个goroutine之间共享一个内存映射文件。每个goroutine都需要逐行迭代文件,因此我希望先将完整内容存储在内存中,以加快速度 我尝试的方法是将指针传递给bufio.Scanner,但这不起作用。我认为这可能与需要将seek位置设置回文件的开头有关,但它第一次甚至不起作用,我在文档中找不到这样的参数。我的尝试是创建这个函数,然后通过引用我打算在goroutine中运行的函数来传递结果(目前,我使用goroutines并不仅仅是为了确保它完全有效,而不是这样) 这里是一个MW
bufio.Scanner
,但这不起作用。我认为这可能与需要将seek位置设置回文件的开头有关,但它第一次甚至不起作用,我在文档中找不到这样的参数。我的尝试是创建这个函数,然后通过引用我打算在goroutine中运行的函数来传递结果(目前,我使用goroutines并不仅仅是为了确保它完全有效,而不是这样)
这里是一个MWE:
// ... package declaration; imports; yada yada
func main() {
// ... validate path to file stored in filePath variable
filePath := "/path/to/file.txt"
// get word list scanner to be shared between goroutines
scanner := getScannerPtr(&filePath)
// pass to function (no goroutine for now, I try to solve one problem at a time)
myfunc(scanner)
}
func getScannerPtr(filePath *string) *bufio.Scanner {
f, err := os.Open(*filePath)
if err != nil {
fmt.Fprint(os.Stderr, "Error opening file\n")
panic(err)
}
defer f.Close()
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
return scanner
}
func myfunc(scanner *bufio.Scanner) {
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
// ... do something with line
}
}
我没有收到任何错误,只是当我调用Scan()
时,它没有在文件上迭代,所以它永远不会在该块中对文件的每一行执行任何操作。请记住,我甚至还没有使用并发,这只是我想要指出的最终目标,以防它影响我需要采取的方法
- 为什么
不工作Scan()
- 如果我打算在将来调用
,这是一种可行的方法吗go-myfunc(scanner)
扫描仪之前,您正在关闭文件:
func getScannerPtr(filePath *string) *bufio.Scanner {
f, err := os.Open(*filePath)
if err != nil {
fmt.Fprint(os.Stderr, "Error opening file\n")
panic(err)
}
defer f.Close() // <--- Here
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
return scanner // <-- File gets closed, then Scanner that tries to read it is returned for further use, which won't work
}
在使用扫描仪之前,您正在关闭文件:
func getScannerPtr(filePath *string) *bufio.Scanner {
f, err := os.Open(*filePath)
if err != nil {
fmt.Fprint(os.Stderr, "Error opening file\n")
panic(err)
}
defer f.Close() // <--- Here
scanner := bufio.NewScanner(f)
scanner.Split(bufio.ScanLines)
return scanner // <-- File gets closed, then Scanner that tries to read it is returned for further use, which won't work
}
是的,它是有效的。您是否绝对确定filePath
处的文件中有数据?另外请注意,scanner.Split(bufio.ScanLines)
是不必要的,因为这是scanner
的默认SplitFunc
。不过,刚才看到了问题并发布了答案。SplitFunc
上的注释仍然有效。是的,它是有效的。您是否绝对确定filePath
处的文件中有数据?另外请注意,scanner.Split(bufio.ScanLines)
是不必要的,因为这是scanner
的默认SplitFunc
。不过,刚才看到了问题并发布了答案。尽管如此,SplitFunc
上的注释仍然有效。因此,在我尝试将scanner作为指针传递之前,该代码实际上起到了作用,以包含在defer f.Close()
语句中。我当时的印象是,这个文件已经在记忆中了?(显然我很困惑,只是想学围棋)不,文件不在内存中Scanner
将文件读入缓冲区,但只能读入有限的字节数,直到调用了Scan
。啊哈,这很有意义。我会试一试,如果成功的话就接受。非常感谢。好了,现在它正在文件上迭代,这样部分问题就解决了!(但不幸的是,它不像以前那样工作,arg——继续下一个bug…)。谢谢是的,如果他们共享扫描仪,你希望关闭
在goroutines之外。只要确保您使用了WaitGroup
,这样您就不会关闭它,直到他们都处理完为止。因此,在我尝试将scanner作为指针传递之前,此代码实际上起到了作用,以包含在defer f.close()
语句中。我当时的印象是,这个文件已经在记忆中了?(显然我很困惑,只是想学围棋)不,文件不在内存中Scanner
将文件读入缓冲区,但只能读入有限的字节数,直到调用了Scan
。啊哈,这很有意义。我会试一试,如果成功的话就接受。非常感谢。好了,现在它正在文件上迭代,这样部分问题就解决了!(但不幸的是,它不像以前那样工作,arg——继续下一个bug…)。谢谢是的,如果他们共享扫描仪,你希望关闭
在goroutines之外。只要确保你使用了一个WaitGroup
,这样你就不会关闭它,直到他们都处理完为止。