Невозможно пройти по папке, используя группу ожидания - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть этот простой сценарий, чтобы попытаться обойти файловую систему и построчно прочитать файлы, чтобы найти строки в регулярном выражении:

package main

import (
  "bufio"
  "fmt"
  "io/ioutil"
  "log"
  "os"
  "regexp"
  "sync"
)

type FileWithLine struct{
  Line int
  Path string
}

var set = map[string]FileWithLine{}
var rgx = regexp.MustCompile("ErrId\\s*:\\s*\"[[:alnum:]]+\"");


func traverseDir(d string, wg *sync.WaitGroup){

  fmt.Println("traversing dir:", d)

  if d == ".git"{
    return
  }

  wg.Add(1)
  go func(wg *sync.WaitGroup){

    defer wg.Done()

    files, err := ioutil.ReadDir(d)

    if err != nil {
      log.Fatal(err)
    }

    for _, f := range files {

      fmt.Println("we see file:", f.Name())

      if f.IsDir() {
       traverseDir(f.Name(), wg)
       return
      }

      file, err := os.Open(f.Name())

      if err != nil {
       log.Fatalf("failed opening file: %s", err)
      }

      scanner := bufio.NewScanner(file)
      scanner.Split(bufio.ScanLines)


      for scanner.Scan() {
      var line = scanner.Text()

      if rgx.MatchString(line) {
        fmt.Println("line matches:", line);
      }

      }

      file.Close()


    }

  }(wg)


}

func main()  {
  var wg sync.WaitGroup
  traverseDir(".", &wg)
  fmt.Println("Main: Waiting for workers to finish")
  wg.Wait()
  fmt.Println("Main: Completed")
}

проблема в том, что он завершает работу до того, как прочитает все файлы, я получаю этот вывод:

traversing dir: .
Main: Waiting for workers to finish
we see file: .git
traversing dir: .git
Main: Completed

, но в текущем каталоге больше файлов, чем просто. git папка. Просто так получилось, что папка. git является первым элементом в текущем рабочем каталоге и сразу после этого закрывается. Кто-нибудь знает, почему моя программа так интересна?

1 Ответ

3 голосов
/ 01 апреля 2020

Он останавливает обработку из-за этих строк:

if f.IsDir() {
   traverseDir(f.Name(), wg)
   return
}

Когда он видит каталог, он входит в него и немедленно возвращается, не обрабатывая оставшиеся файлы в текущем каталоге. И когда первым увиденным каталогом является «. git», поскольку вы обрабатываете его как исключение, вложенный traverseDir также возвращает.

...