Полное руководство: рекурсивное сканирование каталогов в Golang

Рекурсивное сканирование каталогов является общим требованием во многих приложениях, где вам необходимо обрабатывать файлы и каталоги внутри данного каталога и его подкаталогов. В этой статье блога мы рассмотрим несколько методов в Golang для выполнения рекурсивного сканирования каталогов с примерами кода.

Метод 1: использование filepath.Walk
Функция filepath.Walk обеспечивает простой способ рекурсивного перемещения по каталогам. Он посещает каждый файл или каталог в заданном дереве каталогов и вызывает для каждого функцию обратного вызова.

package main
import (
    "fmt"
    "os"
    "path/filepath"
)
func visit(path string, info os.DirEntry, err error) error {
    if err != nil {
        return err
    }
    if info.IsDir() {
        fmt.Println("Directory:", path)
    } else {
        fmt.Println("File:", path)
    }
    return nil
}
func main() {
    root := "path/to/directory"
    err := filepath.WalkDir(root, visit)
    if err != nil {
        fmt.Printf("Error walking the path %s: %v\n", root, err)
    }
}

Метод 2: использование filepath.Glob
Функция filepath.Glob может использоваться для сопоставления файлов или каталогов с использованием шаблонов подстановочных знаков. Объединив его с filepath.WalkDir, мы можем добиться рекурсивного сканирования каталогов.

package main
import (
    "fmt"
    "os"
    "path/filepath"
)
func main() {
    root := "path/to/directory"
    pattern := filepath.Join(root, "")
    matches, err := filepath.Glob(pattern)
    if err != nil {
        fmt.Printf("Error globbing the path %s: %v\n", pattern, err)
        return
    }
    for _, match := range matches {
        info, err := os.Stat(match)
        if err != nil {
            fmt.Printf("Error getting file info for %s: %v\n", match, err)
            continue
        }
        if info.IsDir() {
            fmt.Println("Directory:", match)
        } else {
            fmt.Println("File:", match)
        }
    }
}

Метод 3: использование пользовательской рекурсивной функции
В качестве альтернативы вы можете реализовать свою собственную рекурсивную функцию с помощью пакета os. Такой подход дает вам больше контроля над процессом обхода.

package main
import (
    "fmt"
    "os"
    "path/filepath"
)
func scanDir(root string) error {
    err := filepath.WalkDir(root, func(path string, info os.DirEntry, err error) error {
        if err != nil {
            return err
        }
        if info.IsDir() {
            fmt.Println("Directory:", path)
        } else {
            fmt.Println("File:", path)
        }
        return nil
    })
    if err != nil {
        return fmt.Errorf("Error walking the path %s: %v", root, err)
    }
    return nil
}
func main() {
    root := "path/to/directory"
    err := scanDir(root)
    if err != nil {
        fmt.Println(err)
    }
}

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

Не забывайте правильно обрабатывать ошибки и настраивать примеры кода в соответствии со своими потребностями. Удачного сканирования каталогов!