В этой статье я объясню, как получить список файлов внутри папки в файловой системе. Эта задача также называетсяобход дерева, с Go.
Есть две удобные функции stdlib, которые вы можете использовать в зависимости от вашей цели.
Я перечисляю 3 способа: использованиеfilepath.Walk
,ioutil.ReadDir
или жеos.File.Readdir
.
С помощьюfilepath.Walk
Вpath/filepath
Пакет stdlib предоставляет удобную функцию Walk. Однако он автоматически сканирует подкаталоги, поэтому убедитесь, что это именно то, что вам нужно.
Использование очень простое:
package main
import (
“fmt”
“os”
“path/filepath”
)
func main() {
var files []string
<span style="color:#a6e22e">root</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">"/some/folder/to/scan"</span>
<span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">filepath</span>.<span style="color:#a6e22e">Walk</span>(<span style="color:#a6e22e">root</span>, <span style="color:#66d9ef">func</span>(<span style="color:#a6e22e">path</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">info</span> <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">FileInfo</span>, <span style="color:#a6e22e">err</span> <span style="color:#66d9ef">error</span>) <span style="color:#66d9ef">error</span> {
<span style="color:#a6e22e">files</span> = append(<span style="color:#a6e22e">files</span>, <span style="color:#a6e22e">path</span>)
<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
})
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
panic(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>)
}
}
filepath.Walk
принимает строку, указывающую на корневую папку, иWalkFunc
, тип функции с сигнатурой
type WalkFunc func(path string, info os.FileInfo, err error) error
Эта функция вызывается для каждой итерации сканирования папки.
Вinfo
переменная типаos.FileInfo
важно, потому что мы можем получить много информации о текущем файле: имя, размер, режим, время модификации, если это папка или файл, и базовый источник данных.
Например, мы могли бы избежать обработки папок, добавив
if info.IsDir() {
return nil
}
Вы можете исключить (или включить) файлы в фрагмент на основе их расширения, используяfilepath.Ext
и передав путь к файлу:
if filepath.Ext(path) == ".dat" {
return nil
}
Мы могли бы сохранить имя файла вместо пути к файлу, используя
files = append(files, info.Name())
И мы могли бы также определитьWalkFunc
в отдельномзакрытие. Нам просто нужно передать указатель наfiles
вvisit
:
package main
import (
“fmt”
“log”
“os”
“path/filepath”
)
func visit(files []string) filepath.WalkFunc {
return func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Fatal(err)
}
files = append(*files, path)
return nil
}
}
func main() {
var files []string
<span style="color:#a6e22e">root</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">"/some/folder/to/scan"</span>
<span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">filepath</span>.<span style="color:#a6e22e">Walk</span>(<span style="color:#a6e22e">root</span>, <span style="color:#a6e22e">visit</span>(<span style="color:#f92672">&</span><span style="color:#a6e22e">files</span>))
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
panic(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>)
}
}
С помощьюioutil.ReadDir
filepath.Walk
это удобно, но по умолчанию сканирует и вложенные папки, что может быть не тем, что вам нужно.
Go stdlib также предоставляетioutil.ReadDir
func ReadDir(dirname string) ([]os.FileInfo, error)
ReadDir читает каталог с именем dirname и возвращает список записей каталога, отсортированных по имени файла.
а вот пример из документации.ioutil.ReadDir
принимает путь к папке в виде строки и возвращает фрагментos.FileInfo
, который мы описали выше.
package main
import (
“fmt”
“io/ioutil”
“log”
)
func main() {
files, err := ioutil.ReadDir(".")
if err != nil {
log.Fatal(err)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>.<span style="color:#a6e22e">Name</span>())
}
}
С помощьюos.File.Readdir
Внутриioutil.ReadDir
реализован как
// ReadDir reads the directory named by dirname and returns
// a list of directory entries sorted by filename.
func ReadDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
return nil, err
}
list, err := f.Readdir(-1)
f.Close()
if err != nil {
return nil, err
}
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
return list, nil
}
как вы можете видеть это сканированиеdirname
и сортирует файлы по имени. Если вам не нужна сортировка, вы также можете использовать
package main
import (
“fmt”
“log”
“os”
)
func main() {
dirname := “.”
<span style="color:#a6e22e">f</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Open</span>(<span style="color:#a6e22e">dirname</span>)
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
}
<span style="color:#a6e22e">files</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">Readdir</span>(<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>)
<span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">Close</span>()
<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
<span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Fatal</span>(<span style="color:#a6e22e">err</span>)
}
<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">file</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">files</span> {
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">file</span>.<span style="color:#a6e22e">Name</span>())
}
}
Больше руководств по go:
- Использование обратного прокси NGINX для обслуживания сервисов Go
- Создание копии структуры в Go
- Основы веб-сервера Go
- Сортировка типа карты в Go
- Вкратце об указателях Go
- Объяснение тегов Go
- Форматирование даты и времени Go
- Обработка JSON с помощью Go
- Перейти к переменным функциям
- Шпаргалка по струнам Go
- Объяснение интерфейса Go Empty
- Отладка Go с помощью VS Code и Delve
- Именованный Go возвращает параметры
- Генерация случайных чисел и строк в Go
- Структура файловой системы проекта Go
- Алгоритм двоичного поиска, реализованный в Go
- Использование флагов командной строки в Go
- GOPATH объяснил
- Создайте приложение командной строки с помощью Go: lolcat
- Создание команды интерфейса командной строки с помощью Go: cowsay
- Использование Shell Pipes с Go
- Учебник по интерфейсу командной строки: Fortune Clone
- Перечислить файлы в папке с помощью Go
- Используйте Go, чтобы получить список репозиториев с GitHub
- Пойдите, добавьте фрагмент строк в файл
- Пойдите, преобразуйте строку в срез байтов
- Визуализируйте свой вклад в Git с помощью Go
- Начало работы с Go CPU и профилирование памяти
- Устранение ошибки "не поддерживает индексацию" в программе Go
- Измерение времени выполнения в программе Go
- Создание веб-краулера с Go для обнаружения повторяющихся заголовков
- Go Best Practices: указатель или приемники значений?
- Go Best Practices: следует ли использовать метод или функцию?
- Структуры данных Go: установить
- Шпаргалка по картам Go
- Создание реализаций для универсальных типов в Go
- Структуры данных Go: словарь
- Структуры данных Go: хеш-таблица
- Реализуйте прослушиватели событий в проходных каналах
- Структуры данных Go: стек
- Структуры данных Go: очередь
- Структуры данных Go: двоичное дерево поиска
- Структуры данных Go: график
- Структуры данных Go: связанный список
- Полное руководство по структурам данных Go
- Сравнение значений Go
- Является ли Go объектно-ориентированным?
- Работа с базой данных SQL в Go
- Использование переменных среды в Go
- Учебник: REST API на базе PostgreSQL
- Включение CORS на веб-сервере Go
- Развертывание приложения Go в контейнере Docker
- Почему Go - мощный язык для изучения PHP-разработчика
- Пойдите, удалите символ новой строки io.Reader.ReadString
- Идите, как посмотреть изменения и пересобрать вашу программу
- Иди, посчитай месяцы с даты
- Доступ к параметрам HTTP POST в Go