Функция filepath.Walk

Функция filepath.Walk рекурсивно обходит файловое дерево, начиная с указанного корневого пути. Она принимает два параметра: первый параметр — это путь к корневой директории для обхода, второй параметр — функция обратного вызова WalkFunc, которая вызывается для каждого файла или директории. Если функция обратного вызова возвращает ошибку, обход может быть прерван.

Синтаксис

gofilepath.Walk(rootPath, walkFunc)

Пример

Давайте обойдем текущую директорию и выведем пути всех файлов и поддиректорий:

gopackage main

import (
  "fmt"
  "path/filepath"
)

func main() {
  err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
    if err != nil {
      return err
    }
    fmt.Println(path)
    return nil
  })
  if err != nil {
    fmt.Println(err)
  }
}

Результат выполнения кода (зависит от структуры директорий):

go"."
"./file1.txt"
"./dir1"
"./dir1/file2.txt"

Пример

Давайте обойдем директорию и соберем все пути файлов с расширением .go:

gopackage main

import (
  "fmt"
  "path/filepath"
  "os"
  "strings"
)

func main() {
  var goFiles []string

  err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
    if err != nil {
      return err
    }
    if !info.IsDir() && strings.HasSuffix(info.Name(), ".go") {
      goFiles = append(goFiles, path)
    }
    return nil
  })
  if err != nil {
    fmt.Println(err)
  }
  fmt.Println(goFiles)
}

Результат выполнения кода:

go["./main.go" "./pkg/helper.go" "./internal/utils.go"]

Пример

Давайте обойдем директорию и проверим, существует ли файл с определенным именем:

gopackage main

import (
  "fmt"
  "path/filepath"
  "os"
)

func main() {
  target := "config.yaml"
  found := false

  err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
    if err != nil {
      return err
    }
    if !info.IsDir() && info.Name() == target {
      found = true
      return filepath.SkipDir // останавливаем обход
    }
    return nil
  })
  if err != nil {
    fmt.Println(err)
  }
  fmt.Println(found)
}

Результат выполнения кода:

gotrue

Пример

Давайте обойдем директорию и вычислим общий размер всех файлов:

gopackage main

import (
  "fmt"
  "path/filepath"
  "os"
)

func main() {
  var totalSize int64

  err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
    if err != nil {
      return err
    }
    if !info.IsDir() {
      totalSize += info.Size()
    }
    return nil
  })
  if err != nil {
    fmt.Println(err)
  }
  fmt.Println(totalSize)
}

Результат выполнения кода:

go1234567

Смотрите также

  • функцию filepath.WalkDir,
    которая является более эффективной альтернативой для обхода файловой системы
  • функцию filepath.Glob,
    которая ищет файлы по шаблону в директории
  • функцию os.ReadDir,
    которая читает содержимое директории без рекурсивного обхода
  • функцию filepath.Join,
    которая объединяет пути с правильным разделителем