Goでディレクトリを一覧表示する


197

Goの単一のディレクトリにあるファイルとフォルダーを単純に一覧表示する方法を理解しようとしています。

は見つかりましたがfilepath.Walk、自動的にサブディレクトリに入ります。他のすべての検索では、何も改善されていません。

この機能は確かにあると思いますが、見つけるのは本当に大変でした。誰かが私がどこを見ればよいか知っているなら私に知らせてください。ありがとう。

回答:


359

パッケージのReadDir関数を使用してみてくださいio/ioutil。ドキュメントごと:

ReadDirは、dirnameで指定されたディレクトリを読み取り、ソートされたディレクトリエントリのリストを返します。

結果のスライスにはos.FileInfoここにリストさたメソッドを提供するタイプが含まれます。現在のディレクトリにあるすべての名前をリストする基本的な例を次に示します(フォルダーは含まれていますが、特別にマークされていません- 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())
    }
}

7
あなただけしたい場合は名前のディレクトリとスピードの内容を本質である、使用することに注意してくださいReaddirnamesこと桁違いに速い(周りに20倍速く私のために)
SquattingSlavInTracksuit

2
@SquattingSlavInTracksuit:現時点ではコメント権限を持っていなかったため、ここでコメントを回答に昇格させました。LMKに答えてクレジットを取得したい場合は、
Jacob Kopczynski

2
@SquattingSlavInTracksuit-これは1桁だけです:P
nadavvadan

78

さらにシンプルに、以下を使用します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
Glob ignores file system errors such as I/O errors reading directories. The only possible returned error is ErrBadPattern, when pattern is malformed.
2015年

3
Globを使用する前に、Globの機能を必ず理解してください。 golang.org/pkg/path/filepath/#Glob
Anfernee

66

さまざまなgolang標準ライブラリ関数を使用して、ファイルシステムのフォルダー内のファイルのリストを取得できます。

  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の使用

path/filepathパッケージには、ディレクトリ内のすべてのファイルをスキャンする便利な方法を提供し、それが自動的にディレクトリ内の各サブディレクトリをスキャンします。

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. ioutil.ReadDirの使用

ioutil.ReadDir dirnameで指定されたディレクトリを読み取り、ファイル名でソートされたディレクトリエントリのリストを返します。

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の使用

Readdirは、ファイルに関連付けられたディレクトリの内容を読み取り、Lstatによって返されるように、ディレクトリ順に最大n個のFileInfo値のスライスを返します。同じファイルに対する後続の呼び出しでは、さらにFileInfoが生成されます。

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
}

ベンチマーク結果。

ベンチマークスコア

このブログ投稿の詳細を取得する


3
ここで最も完全な答え。このベンチマークで報告されているメモリ使用量や割り当てがないことは注目に値します。より高速な実装がより多くのメモリを使用する可能性があります。テスターのコンピューター上のCPUコアの数がコンカレントを傷つけたり、助けたりすることも可能ですfilepath.Walk。さらに、filepath.Walk再帰的なまともなサポートをos.File.Readdir行いioutil.ReadDirます。
Xeoncross

24

ioutil.ReadDir良い検索ですが、ソースをクリックしてソースを見ると、それがos.FileのメソッドReaddirを呼び出していることがわかります。ディレクトリの順序に問題がなく、リストをソートする必要がない場合は、このReaddirメソッドで十分です。


7

あなたの説明から、おそらくあなたが望むのはos.Readdirnamesです。

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

Readdirnamesは、ファイルに関連付けられたディレクトリの内容を読み取り、ディレクトリ内の最大n個のファイル名のスライスをディレクトリ順に返します。同じファイルを続けて呼び出すと、さらに名前が付けられます。

...

n <= 0の場合、Readdirnamesは1つのスライスのディレクトリからすべての名前を返します。

スニペット:

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

SquattingSlavInTracksuitコメントのクレジット。可能であれば、回答へのコメントの昇格を提案しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.