IT박스

Golang에서 파일 시스템 스캔을 수행하는 방법은 무엇입니까?

itboxs 2020. 8. 23. 08:43
반응형

Golang에서 파일 시스템 스캔을 수행하는 방법은 무엇입니까?


  1. 폴더의 경로가 주어지면 해당 폴더에있는 파일을 검색하는 함수를 작성해야합니다.
  2. 그런 다음 해당 폴더의 디렉토리 구조를 표시해야합니다.

2하는 방법을 알고 있습니다 (jstree를 사용하여 브라우저에 표시 할 것입니다).

go에서 그러한 함수를 작성하기 위해 무엇을 / 어디에서 시작하는지와 같은 파트 1을 도와주세요.


편집 : 충분한 사람들이 여전히이 답변을 쳤으므로 Go1 API에 대해 업데이트 할 것이라고 생각했습니다. 이것은 filepath.Walk () 의 작동 예제입니다 . 원본은 아래와 같습니다.

package main

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

func visit(path string, f os.FileInfo, err error) error {
  fmt.Printf("Visited: %s\n", path)
  return nil
} 


func main() {
  flag.Parse()
  root := flag.Arg(0)
  err := filepath.Walk(root, visit)
  fmt.Printf("filepath.Walk() returned %v\n", err)
}

filepath.Walk는 디렉토리 트리를 재귀 적으로 탐색합니다.

다음은 실행 예입니다.

$ mkdir -p dir1/dir2
$ touch dir1/file1 dir1/dir2/file2
$ go run walk.go dir1
Visited: dir1
Visited: dir1/dir2
Visited: dir1/dir2/file2
Visited: dir1/file1
filepath.Walk() returned <nil>

원래 답변 : 걷기 파일 경로의 인터페이스가 매주 변경되었습니다 . 2011-09-16, http://groups.google.com/group/golang-nuts/msg/e304dd9cf196a218을 참조하세요 . 아래 코드는 가까운 시일 내에 GO 릴리스 버전에서 작동하지 않습니다.

실제로 이것을위한 표준 lib에는 filepath.Walk 함수가 있습니다.

package main

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

type visitor int

// THIS CODE NO LONGER WORKS, PLEASE SEE ABOVE
func (v visitor) VisitDir(path string, f *os.FileInfo) bool {
    println(path)
    return true
} 

func (v visitor) VisitFile(path string, f *os.FileInfo) {
    println(path)
}

func main() {
    root := flag.Arg(0)
    filepath.Walk(root, visitor(0), nil)
}

다음은 디렉토리의 파일에 대한 파일 정보를 얻는 방법입니다.

package main

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

func main() {
    dirname := "." + string(filepath.Separator)
    d, err := os.Open(dirname)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    defer d.Close()
    fi, err := d.Readdir(-1)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    for _, fi := range fi {
        if fi.Mode().IsRegular() {
            fmt.Println(fi.Name(), fi.Size(), "bytes")
        }
    }
}

다음은 모든 파일과 디렉토리를 재귀 적으로 반복하는 예제입니다. 추가하려는 경로가 디렉토리인지 알고 싶다면 "f.IsDir ()"을 확인하십시오.

package main

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

func main() {
    searchDir := "c:/path/to/dir"

    fileList := []string{}
    err := filepath.Walk(searchDir, func(path string, f os.FileInfo, err error) error {
        fileList = append(fileList, path)
        return nil
    })

    for _, file := range fileList {
        fmt.Println(file)
    }
}

패키지 github.com/kr/fsWalker매우 흥미로운 API를 제공합니다 .


Go 표준 패키지 ioutil에는이 사례 시나리오에 대한 기능이 내장되어 있습니다 (아래 예제 참조).

func searchFiles(dir string) { // dir is the parent directory you what to search
    files, err := ioutil.ReadDir(dir)
    if err != nil {
        log.Fatal(err)
    }

    for _, file := range files {
        fmt.Println(file.Name())
    }
}

Note that "Walk does not follow symbolic links" so if you are looking to write a function that does that I recommend ioutil.ReadDir. My own benchmark test showed that it is faster and less memory intensive than filepath.Glob.

Additionally, ioutil.ReadDir is sorting files by basename using basic string comparison (strA > strB). As a devops guy, I generally sort dir names by doing a reverse numerical comparison (latest build first for example). If that is also your case then it is better to call os.ReadDir directly (ioutil.ReadDir is calling this under the covers) and do the sorting yourself.

Here is an example of the ReadDir part with Numerical sort:

// ReadDirNumSort - Same as ioutil/ReadDir but uses returns a Numerically
// Sorted file list.
//
// Taken from https://golang.org/src/io/ioutil/ioutil.go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// Modified Sort method to use Numerically sorted names instead.
// It also allows reverse sorting.
func ReadDirNumSort(dirname string, reverse bool) ([]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
    }
    if reverse {
        sort.Sort(sort.Reverse(byName(list)))
    } else {
        sort.Sort(byName(list))
    }
    return list, nil
}

// byName implements sort.Interface.
type byName []os.FileInfo

func (f byName) Len() int      { return len(f) }
func (f byName) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
func (f byName) Less(i, j int) bool {
    nai, err := strconv.Atoi(f[i].Name())
    if err != nil {
        return f[i].Name() < f[j].Name()
    }
    naj, err := strconv.Atoi(f[j].Name())
    if err != nil {
        return f[i].Name() < f[j].Name()
    }
    return nai < naj
}

참고URL : https://stackoverflow.com/questions/6608873/how-to-perform-file-system-scanning-in-golang

반응형