读取文件时跳过数据

问题描述 投票:0回答:1

我的任务是编写一个日志解析器。路径切片作为路径传递,我想创建每行结构的切片。我想逐行阅读,以免占用大量内存。

一切正常,但有时有些数据来不及写入,因此会发生数据泄漏。我该如何解决这个问题?

func test(matches string) (*domain.NGINX, error) {
    var wg sync.WaitGroup

    logChan := make(chan *domain.NGINX)
    errChan := make(chan error)
    
    var logs []*domain.NGINX
    
    go func() {
        for log := range logChan {
            logs = append(logs, log)
        }
    }()
    
    for _, match := range matches {
        wg.Add(1)
    
        go func(filePath string) {
            defer wg.Done()
    
            file, err := os.Open(filePath)
            if err != nil {
                errChan <- fmt.Errorf("accessing path: %v", err)
                return
            }
            defer file.Close()
    
            scanner := bufio.NewScanner(file)
            for scanner.Scan() {
                line := scanner.Text()
    
                logNGINX, err := ParseLogLineToNGINXObject(line)
                if err != nil {
                    continue
                }
                logChan <- logNGINX
            }
    
            if err := scanner.Err(); err != nil {
                errChan <- fmt.Errorf("scanning file: %v", err)
                return
            }
        }(match)
    }
    
    
    wg.Wait()
    close(logChan)
    close(errChan)
    
    var err error
    for e := range errChan {
        fmt.Printf("Error: %v\n", e)
        err = e
    }
    
    return logs, err

}
go
1个回答
0
投票

正如评论中提到的,写入

errChan
的错误是阻塞的,所以你的 goroutine 会卡在那里。因此,WaitGroup 锁不会被释放,并且你的主 goroutine 会卡在 Wait() 处。

如果您希望在发生错误时使所有读数失败,请尝试

golang.org/x/sync/errgroup
。或者,如果您只想失败一些,请创建一个与
matches
长度相同的 []error 切片,并将错误写入从 for 循环获得的索引处。这并不活泼,因为每个 goroutine 都会访问它的内存。稍后您可以使用
errors.Join
来处理错误,它会为您过滤掉
nil
值。

© www.soinside.com 2019 - 2024. All rights reserved.