cpp

Перебор объектов, расположенных в каталоге

Перебрать все объекты в указанном каталоге можно с помощью следующих функций из пакета path/filepath:

  • Glob() — позволяет получить слайс с путями, соответствующими шаблону. Формат функции:
filepath.Glob(pattern string) (matches []string, err error)

В строке шаблона можно использовать следующие специальные символы:

  • ? — любой одиночный символ;
  • * — любое количество символов;
  • [<Символы>] — позволяет указать символы, которые должны быть на этом месте в пути. Можно перечислить символы или указать диапазон через тире.

Получим все файлы с расширением txt, расположенные в каталоге C:\book:

fmt.Println(filepath.Glob(`C:\book\*.txt`))
// [C:\book\file.txt] <nil>

Получим все объекты, расположенные в каталоге C:\book:

fmt.Println(filepath.Glob(`C:\book\*`))
// [C:\book\file.txt C:\book\packages C:\book\test]
// <nil>

Получим все объекты, расположенные в каталоге C:\book, названия которых начинаются с буквы f или t:

fmt.Println(filepath.Glob(`C:\book\[ft]*`))
// [C:\book\file.txt C:\book\test] <nil>
  • Walk() — позволяет обойти дерево каталогов. Формат функции:
filepath.Walk(root string, fn filepath.WalkFunc) error

Для каждого файла или каталога вызывается функция WalkFunc, которая принимает три параметра. Через первый параметр доступен текущий путь, через второй — информация об элементе в виде объекта, реализующего интерфейс fs.FileInfo (см. разд. 15.4), а через третий — информация об ошибке. Функция должна возвращать объект ошибки или значение nil. Если возвращается значение nil, то производится переход к следующему объекту. Чтобы пропустить просмотр каталога нужно вернуть значение filepath.SkipDir. Если возвращается другая ошибка, то просмотр останавливается и функция Walk() возвращает эту ошибку. Пример:

filepath.Walk(`C:\book\packages`,
   func(path string, info fs.FileInfo, err error) error {
      if err != nil {
         fmt.Println(err)
         return err
      }
      fmt.Println(path, info.IsDir())
      // Пропускаем содержимое каталога C:\book\packages\.vscode
      if info.IsDir() && info.Name() == `.vscode` {
         return filepath.SkipDir
      }
      return nil
   })

Результат:

C:\book\packages true
C:\book\packages\.vscode true
C:\book\packages\functions true
C:\book\packages\functions\functions.go false
C:\book\packages\functions\point.go false
C:\book\packages\go.mod false
C:\book\packages\go.sum false
C:\book\packages\main.exe false
C:\book\packages\main.go false
C:\book\packages\main_test.go false
  • WalkDir() — позволяет обойти дерево каталогов. Формат функции:
filepath.WalkDir(root string, fn fs.WalkDirFunc) error

Для каждого файла или каталога вызывается функция WalkDirFunc, которая принимает три параметра. Через первый параметр доступен текущий путь, через второй — информация об элементе в виде объекта, реализующего интерфейс fs.DirEntry, а через третий — информация об ошибке. Функция должна возвращать объект ошибки или значение nil. Если возвращается значение nil, то производится переход к следующему объекту. Чтобы пропустить просмотр каталога нужно вернуть значение filepath.SkipDir. Если возвращается другая ошибка, то просмотр останавливается и функция WalkDir() возвращает эту ошибку. Пример:

filepath.WalkDir(`C:\book\packages`,
   func(path string, d fs.DirEntry, err error) error {
      if err != nil {
         fmt.Println(err)
         return err
      }
      fmt.Println(path, d.IsDir())
      // Пропускаем содержимое каталога C:\book\packages\.vscode
      if d.IsDir() && d.Name() == `.vscode` {
         return filepath.SkipDir
      }
      return nil
   })

Результат:

C:\book\packages true
C:\book\packages\.vscode true
C:\book\packages\functions true
C:\book\packages\functions\functions.go false
C:\book\packages\functions\point.go false
C:\book\packages\go.mod false
C:\book\packages\go.sum false
C:\book\packages\main.exe false
C:\book\packages\main.go false
C:\book\packages\main_test.go false

Интерфейс fs.DirEntry содержит следующие методы:

  • Name() — возвращает название файла или каталога. Формат метода:
(fs.DirEntry).Name() string

Пример:

fmt.Println(d.Name()) // main.go
  • IsDir() — возвращает true, если объект является каталогом, и false — в противном случае. Формат метода:
(fs.DirEntry).IsDir() bool

Пример:

fmt.Println(d.IsDir()) // false
  • Type() — возвращает права доступа для типа (m & fs.ModeType). Формат метода:
(fs.DirEntry).Type() fs.FileMode

Пример:

fmt.Println(d.Type()) // d---------
  • Info() — позволяет получить информацию об элементе. Формат метода:
(fs.DirEntry).Info() (fs.FileInfo, error)

Пример:

info, err := d.Info()
if err != nil {
   fmt.Println(err)
   return err
}
fmt.Println(info.Size())        // 111
fmt.Println(info.Mode().Perm()) // -rw-rw-rw-
fmt.Println(info.ModTime())
// 2022-04-03 21:11:15.2497283 +0300 MSK

Получить слайс с объектами fs.DirEntry, описывающими элементы каталога, позволяет функция ReadDir() из пакета os. Формат функции:

os.ReadDir(name string) ([]fs.DirEntry, error)

Пример перебора объектов, расположенных в каталоге, приведен в листинге 15.2.

Листинг 15.2. Перебор объектов, расположенных в каталоге

package main

import (
   "fmt"
   "os"
)

func main() {
   arr, err := os.ReadDir(`C:\book\packages`)
   if err != nil {
      fmt.Println(err)
      return
   }
   for _, d := range arr {
      fmt.Println(d.Name())
      if d.IsDir() {
         fmt.Println("--- каталог")
      } else {
         fmt.Println("--- файл")
         info, err := d.Info()
         if err != nil {
            fmt.Println(err)
            return
         }
         fmt.Println("--- Size() =", info.Size())
         fmt.Println("--- Mode() =", info.Mode().Perm())
         fmt.Println("--- ModTime() =", info.ModTime())
      }
   }
}

Результат:

.vscode
--- каталог
functions
--- каталог
go.mod
--- файл
--- Size() = 37
--- Mode() = -rw-rw-rw-
--- ModTime() = 2022-04-03 18:43:35.9209749 +0300 MSK
go.sum
--- файл
--- Size() = 0
--- Mode() = -rw-rw-rw-
--- ModTime() = 2022-04-03 18:43:19.5291327 +0300 MSK
main.exe
--- файл
--- Size() = 1927168
--- Mode() = -rw-rw-rw-
--- ModTime() = 2022-03-31 22:52:10.138014 +0300 MSK
main.go
--- файл
--- Size() = 111
--- Mode() = -rw-rw-rw-
--- ModTime() = 2022-04-03 21:11:15.2497283 +0300 MSK
main_test.go
--- файл
--- Size() = 139
--- Mode() = -rw-rw-rw-
--- ModTime() = 2022-04-03 22:22:25.9879898 +0300 MSK

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Реквизиты

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp