Я пытаюсь обойти файловую структуру в ширину первым способом. Я получаю нарушение сегментации - PullRequest
1 голос
/ 27 февраля 2020

Я знаю о ioutil.ReadDir и os.filePath, но ни один из них не пересекает каталог в Breadth первым способом. Мой подход заключается в том, чтобы вызвать ioutil.ReadDir и добавить все содержимое root dir в слайс. Затем я перебираю содержимое и проверяю, является ли оно IsDir[], и рекурсивно вызываю функцию, если true.

package main

import (
    "io/ioutil"
    "os"
)

var files []string
var path string

func appendFiles(root string) {
    fileInfo, err := ioutil.ReadDir(root)
    if err != nil {
        return
    }
    for _, file := range fileInfo {
        files = append(files, file.Name())
    }

    for _, file := range fileInfo {
        fileStat, _ := os.Stat(file.Name())
        if fileStat.Mode().IsDir() {
            // path = path + "/" + file.Name()
            appendFiles(file.Name())
        }
    }
}

func main() {

    appendFiles(".")
}

1 Ответ

2 голосов
/ 27 февраля 2020

Проблема в том, что os.Stat() может вернуть error, который вы пропустите. Когда это случается, fileStat может быть nil, поэтому паника вызывает fileStat.Mode() в следующей строке.

И причина os.Stat() в том, что file.Name() относительно root, * Сам по себе 1013 * имеет мало шансов на существование, его нужно соединить с root. Если os.Stat() вызывается с несуществующим именем файла, он возвращает nil информацию о файле и ошибку, отличную от nil.

Вы можете использовать filepath.Join() создать правильный путь для файлов, с которыми os.Stat() будет работать. И было бы лучше обрабатывать ошибки, например возвращать их, которые вы можете проверить в main().

func appendFiles(root string) error {
    fileInfo, err := ioutil.ReadDir(root)
    if err != nil {
        return fmt.Errorf("ReadDir error: %w", err)
    }
    for _, file := range fileInfo {
        files = append(files, filepath.Join(root, file.Name()))
    }

    for _, file := range fileInfo {
        fullName := filepath.Join(root, file.Name())
        fileStat, err := os.Stat(fullName)
        if err != nil {
            return fmt.Errorf("Stat error: %w", err)
        }
        if fileStat.Mode().IsDir() {
            if err := appendFiles(fullName); err != nil {
                return fmt.Errorf("appendFiles error: %w", err)
            }
        }
    }
    return nil
}

func main() {
    if err := appendFiles("."); err != nil {
        fmt.Println(err)
    }
}
...