Go'daki liste dizini


198

Go'da tek bir dizindeki dosyaları ve klasörleri nasıl listeleyeceğinizi anlamaya çalışıyorum.

Buldum filepath.Walk, ancak istemediğim otomatik olarak alt dizinlere gider. Diğer tüm aramalarım daha iyi bir şey yapmadı.

Bu işlevin var olduğundan eminim, ancak bulmak gerçekten zor oldu. Nereye bakmam gerektiğini bilen biri varsa bana bildirin. Teşekkürler.

Yanıtlar:


360

Paketteki ReadDir işlevini kullanmayı deneyebilirsiniz io/ioutil. Dokümanlar başına:

ReadDir, dirname adlı adlı dizini okur ve sıralanan dizin girişlerinin listesini döndürür.

Ortaya çıkan dilim, buradaos.FileInfo listelenen yöntemleri sağlayan türleri içerir . Geçerli dizindeki her şeyin adını listeleyen temel bir örnek (klasörler dahil edilir, ancak özel olarak işaretlenmez - bir öğenin yöntemi kullanarak bir klasör olup olmadığını kontrol edebilirsiniz ):IsDir()

package main

import (
    "fmt"
    "io/ioutil"
     "log"
)

func main() {
    files, err := ioutil.ReadDir("./")
    if err != nil {
        log.Fatal(err)
    }

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

8
Yalnızca bir dizinin içeriğinin adlarını ve hızının temel olmasını istiyorsanız , Readdirnames'i kullanmanın daha hızlı büyüklük sırası olduğunu unutmayın (benim için yaklaşık 20 kat daha hızlı)
SquattingSlavInTracksuit

2
@SquattingSlavInTracksuit: Yorumunuzu bir cevaba yükselttim, çünkü o sırada yorum ayrıcalıklarım yoktu. Cevap vermeyi ve krediyi almayı tercih ederseniz, LMK.
Jacob Kopczynski

2
@SquattingSlavInTracksuit - bu sadece bir büyüklük sırası: P
nadavvadan

79

Daha da basit kullanın path/filepath:

package main    

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

func main() {
    files, err := filepath.Glob("*")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(files) // contains a list of all files in the current directory
}

8
UnutmayınGlob ignores file system errors such as I/O errors reading directories. The only possible returned error is ErrBadPattern, when pattern is malformed.
Jon

3
Glob'u kullanmadan önce ne yaptığını anladığınızdan emin olun. golang.org/pkg/path/filepath/#Glob
Anfernee

69

Çeşitli golang standart kütüphane işlevlerini kullanarak dosya sistemindeki bir klasör içindeki dosyaların bir listesini alabiliriz.

  1. filepath.Walk
  2. ioutil.ReadDir
  3. os.File.Readdir

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "os"
    "path/filepath"
)

func main() {
    var (
        root  string
        files []string
        err   error
    )

    root := "/home/manigandan/golang/samples"
    // filepath.Walk
    files, err = FilePathWalkDir(root)
    if err != nil {
        panic(err)
    }
    // ioutil.ReadDir
    files, err = IOReadDir(root)
    if err != nil {
        panic(err)
    }
    //os.File.Readdir
    files, err = OSReadDir(root)
    if err != nil {
        panic(err)
    }

    for _, file := range files {
        fmt.Println(file)
    }
}
  1. Filepath.Walk kullanma

path/filepathPaket, otomatik olarak dizindeki her bir alt dizinleri tarayacak bir dizindeki tüm dosyaları taramak için kullanışlı bir yol sağlar.

func FilePathWalkDir(root string) ([]string, error) {
    var files []string
    err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
        if !info.IsDir() {
            files = append(files, path)
        }
        return nil
    })
    return files, err
}
  1. İoutil.ReadDir kullanma

ioutil.ReadDir dirname adlı dizini okur ve dosya adına göre sıralanmış dizin girişlerinin listesini döndürür.

func IOReadDir(root string) ([]string, error) {
    var files []string
    fileInfo, err := ioutil.ReadDir(root)
    if err != nil {
        return files, err
    }

    for _, file := range fileInfo {
        files = append(files, file.Name())
    }
    return files, nil
}
  1. Os.File.Readdir kullanma

Readdir, dosya ile ilişkilendirilmiş dizinin içeriğini okur ve Lstat tarafından döndürüleceği gibi, n dizine kadar n FileInfo değerine kadar bir dilim döndürür. Aynı dosyaya yapılan sonraki çağrılar daha fazla FileInfos verecektir.

func OSReadDir(root string) ([]string, error) {
    var files []string
    f, err := os.Open(root)
    if err != nil {
        return files, err
    }
    fileInfo, err := f.Readdir(-1)
    f.Close()
    if err != nil {
        return files, err
    }

    for _, file := range fileInfo {
        files = append(files, file.Name())
    }
    return files, nil
}

Deney sonuçları.

karşılaştırma puanı

Bu Blog Yayını hakkında daha fazla bilgi edinin


3
Burada en eksiksiz cevap. Bu ölçüt tarafından bildirilen bellek kullanımı veya alaşımların olmadığını belirtmek gerekir. Daha hızlı uygulamalar daha fazla bellek kullanır. Test cihazının bilgisayarındaki CPU çekirdeği sayısının aynı anda acı çekmesi / yardımcı olması da mümkündür filepath.Walk. Ayrıca, filepath.Walközyinelemeli terbiyeli iken destekler os.File.Readdirve ioutil.ReadDiretmeyin.
Xeoncross


7

Açıklamanızdan, muhtemelen istediğiniz os.Readdirnames .

func (f *File) Readdirnames(n int) (names []string, err error)

Readdirnames, dosyayla ilişkili dizinin içeriğini okur ve dizindeki en çok n dosya adından oluşan bir dilim dizin sırasına göre döndürür. Aynı dosyaya yapılan sonraki çağrılar başka adlar da verecektir.

...

N <= 0 ise, Readdirnames dizindeki tüm adları tek bir dilim halinde döndürür.

Pasaj:

file, err := os.Open(path)
if err != nil {
    return err
}
names, err := file.Readdirnames(0)
if err != nil {
    return err
}
fmt.Println(names)

Kredi SquattingSlavInTracksuit bireyin comment ; Yapabilseydim, onların cevabını yorumlarına yükseltmeyi önerirdim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.