Go 传递指向bufio.Scanner()的指针

Go 传递指向bufio.Scanner()的指针,go,concurrency,memory-mapped-files,Go,Concurrency,Memory Mapped Files,我的目标是在多个goroutine之间共享一个内存映射文件。每个goroutine都需要逐行迭代文件,因此我希望先将完整内容存储在内存中,以加快速度 我尝试的方法是将指针传递给bufio.Scanner,但这不起作用。我认为这可能与需要将seek位置设置回文件的开头有关,但它第一次甚至不起作用,我在文档中找不到这样的参数。我的尝试是创建这个函数,然后通过引用我打算在goroutine中运行的函数来传递结果(目前,我使用goroutines并不仅仅是为了确保它完全有效,而不是这样) 这里是一个MW

我的目标是在多个goroutine之间共享一个内存映射文件。每个goroutine都需要逐行迭代文件,因此我希望先将完整内容存储在内存中,以加快速度

我尝试的方法是将指针传递给
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
,这样你就不会关闭它,直到他们都处理完为止。