รายการไดเรกทอรีใน Go


198

ฉันพยายามหาวิธีแสดงรายการไฟล์และโฟลเดอร์ในไดเรกทอรีเดียวใน Go

ฉันเจอfilepath.Walkแล้ว แต่มันเข้าสู่ไดเรกทอรีย่อยโดยอัตโนมัติซึ่งฉันไม่ต้องการ การค้นหาอื่น ๆ ทั้งหมดของฉันไม่ได้ทำให้ดีขึ้น

ฉันแน่ใจว่ามีฟังก์ชั่นนี้อยู่ แต่หาได้ยากจริงๆ แจ้งให้เราทราบหากใครรู้ว่าฉันควรมองที่ไหน ขอบคุณ

คำตอบ:


360

คุณสามารถลองใช้ฟังก์ชัน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())
    }
}

8
หากคุณต้องการชื่อของเนื้อหาของไดเรกทอรีและความเร็วเป็นสิ่งสำคัญโปรดทราบว่าการใช้Readdirnamesเป็นคำสั่งที่มีขนาดเร็วกว่า (เร็วกว่าประมาณ 20 เท่าสำหรับฉัน)
SquattingSlavInTracksuit

2
@SquattingSlavInTracksuit: ฉันเลื่อนระดับความคิดเห็นของคุณที่นี่เป็นคำตอบเพราะฉันไม่มีสิทธิ์แสดงความคิดเห็นในเวลานั้น หากคุณต้องการตอบคำถามและรับเครดิต LMK
Jacob Kopczynski

2
@SquattingSlavInTracksuit - นั่นเป็นเพียงลำดับความสำคัญ: P
nadavvadan

79

ง่ายยิ่งขึ้นใช้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.
Jon

3
โปรดเข้าใจว่า Glob ทำอะไรก่อนใช้งาน golang.org/pkg/path/filepath/#Glob
Anfernee

69

เราสามารถรับรายชื่อไฟล์ภายในโฟลเดอร์ในระบบไฟล์โดยใช้ฟังก์ชั่นไลบรารีมาตรฐานต่างๆของ 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 อ่านเนื้อหาของไดเรกทอรีที่เกี่ยวข้องกับไฟล์และคืนค่าส่วนต่างของค่า FileInfo สูงสุด n ค่าตามที่ Lstat ส่งคืนตามลำดับของไดเร็กทอรี การเรียกไฟล์ที่ตามมาครั้งต่อไปจะให้ผล FileInfos เพิ่มเติม

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สนับสนุน recursive ที่ดีในขณะที่os.File.Readdirและioutil.ReadDirไม่
Xeoncross

24

ioutil.ReadDirเป็นที่หาที่ดี แต่ถ้าคุณคลิกและดูที่มาที่คุณเห็นว่ามันเรียกวิธีการreaddir ของ os.File หากคุณไม่เป็นไรกับคำสั่งไดเรกทอรีและไม่จำเป็นต้องเรียงลำดับรายการวิธีการอ่านนี้เป็นสิ่งที่คุณต้องการ


7

จากคำอธิบายของคุณสิ่งที่คุณอาจต้องการเป็นos.Readdirnames

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

Readdirnames อ่านเนื้อหาของไดเรกทอรีที่เกี่ยวข้องกับไฟล์และส่งคืนส่วนของชื่อไฟล์ในไดเรกทอรีตามลำดับไดเรกทอรีสูงสุด n ชื่อ การเรียกไฟล์ที่ตามมาครั้งต่อไปจะให้ชื่อเพิ่มเติม

...

ถ้า n <= 0, Readdirnames จะส่งคืนชื่อทั้งหมดจากไดเรกทอรีในส่วนเดียว

ตัวอย่างข้อมูล:

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

เครดิตSquattingSlavInTracksuit 's ความคิดเห็น ; ฉันขอแนะนำให้โปรโมตความคิดเห็นเพื่อหาคำตอบถ้าทำได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.