我一直在尝试如何在Go中简单地列出单个目录中的文件和文件夹。
我找到文件路径了。Walk,但它会自动进入子目录,这是我不想要的。我其他的搜索都没有更好的结果。
我相信这个功能是存在的,但它真的很难找到。如果有人知道我该去哪里找,请告诉我。谢谢。
我一直在尝试如何在Go中简单地列出单个目录中的文件和文件夹。
我找到文件路径了。Walk,但它会自动进入子目录,这是我不想要的。我其他的搜索都没有更好的结果。
我相信这个功能是存在的,但它真的很难找到。如果有人知道我该去哪里找,请告诉我。谢谢。
当前回答
从您的描述中,您可能需要的是os.Readdirnames。
func (f *File) Readdirnames(n int) (names[]字符串,err错误) Readdirnames读取与file相关的目录的内容,并按目录顺序返回该目录中最多n个文件名的切片。对同一文件的后续调用将产生更多的名称。 ... 如果n <= 0, Readdirnames在一个切片中返回目录中的所有名称。
代码片段:
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
names, err := file.Readdirnames(0)
if err != nil {
return err
}
fmt.Println(names)
归功于SquattingSlavInTracksuit的评论;如果可以的话,我会建议将他们的评论提升为一个答案。
其他回答
从Go 1.16开始,你可以使用操作系统。ReadDir函数。
func ReadDir(名称字符串)([]退行,错误)
它读取一个给定的目录并返回一个包含按文件名排序的目录条目的DirEntry片。
它是一个乐观函数,因此,当读取目录条目时发生错误时,它会尝试返回一个切片,其中包含错误发生前的文件名。
package main
import (
"fmt"
"log"
"os"
)
func main() {
files, err := os.ReadDir(".")
if err != nil {
log.Fatal(err)
}
for _, file := range files {
fmt.Println(file.Name())
}
}
有趣的是:Go 1.17(2021年Q3)包括fs.FileInfoToDirEntry():
func FileInfoToDirEntry(info FileInfo) DirEntry FileInfoToDirEntry返回一个从info返回信息的DirEntry。 如果info为nil, FileInfoToDirEntry返回nil。
背景
Go 1.16 (Q1 2021)将提出基于FS接口的ReadDir函数,使用CL 243908和CL 243914:
// An FS provides access to a hierarchical file system.
//
// The FS interface is the minimum implementation required of the file system.
// A file system may implement additional interfaces,
// such as fsutil.ReadFileFS, to provide additional or optimized functionality.
// See io/fsutil for details.
type FS interface {
// Open opens the named file.
//
// When Open returns an error, it should be of type *PathError
// with the Op field set to "open", the Path field set to name,
// and the Err field describing the problem.
//
// Open should reject attempts to open names that do not satisfy
// ValidPath(name), returning a *PathError with Err set to
// ErrInvalid or ErrNotExist.
Open(name string) (File, error)
}
允许“os: add ReadDir方法用于轻量级目录读取”: 参见commit a4ede9f:
// ReadDir reads the contents of the directory associated with the file f
// and returns a slice of DirEntry values in directory order.
// Subsequent calls on the same file will yield later DirEntry records in the directory.
//
// If n > 0, ReadDir returns at most n DirEntry records.
// In this case, if ReadDir returns an empty slice, it will return an error explaining why.
// At the end of a directory, the error is io.EOF.
//
// If n <= 0, ReadDir returns all the DirEntry records remaining in the directory.
// When it succeeds, it returns a nil error (not io.EOF).
func (f *File) ReadDir(n int) ([]DirEntry, error)
// A DirEntry is an entry read from a directory (using the ReadDir method).
type DirEntry interface {
// Name returns the name of the file (or subdirectory) described by the entry.
// This name is only the final element of the path, not the entire path.
// For example, Name would return "hello.go" not "/home/gopher/hello.go".
Name() string
// IsDir reports whether the entry describes a subdirectory.
IsDir() bool
// Type returns the type bits for the entry.
// The type bits are a subset of the usual FileMode bits, those returned by the FileMode.Type method.
Type() os.FileMode
// Info returns the FileInfo for the file or subdirectory described by the entry.
// The returned FileInfo may be from the time of the original directory read
// or from the time of the call to Info. If the file has been removed or renamed
// since the directory read, Info may return an error satisfying errors.Is(err, ErrNotExist).
// If the entry denotes a symbolic link, Info reports the information about the link itself,
// not the link's target.
Info() (FileInfo, error)
}
src/os/os_test.go#testReadDir()说明了它的用法:
file, err := Open(dir)
if err != nil {
t.Fatalf("open %q failed: %v", dir, err)
}
defer file.Close()
s, err2 := file.ReadDir(-1)
if err2 != nil {
t.Fatalf("ReadDir %q failed: %v", dir, err2)
}
Ben Hoyt在评论中指出Go 1.16 os。ReadDir:
操作系统。ReadDir(路径字符串)([]os. conf)DirEntry, error),您可以直接调用它,而不需要Open舞蹈。 所以你可以把这个缩短为os。ReadDir,因为这是大多数人会调用的具体函数。
参见commit 3d913a9 (december 2020):
os:添加ReadFile, WriteFile, CreateTemp(是TempFile), MkdirTemp(是TempDir)从io/ioutil Io /ioutil是一个定义不佳的帮助程序集合。 提案#40025将通用I/O帮助器移到io。 提案#42026的CL将特定于os的helper移动到os, 弃用整个io/ioutil包。
操作系统。ReadDir返回[]DirEntry,与ioutil相反。ReadDir () FileInfo。 (提供一个返回[]DirEntry的helper是这个更改的主要动机之一。)
从您的描述中,您可能需要的是os.Readdirnames。
func (f *File) Readdirnames(n int) (names[]字符串,err错误) Readdirnames读取与file相关的目录的内容,并按目录顺序返回该目录中最多n个文件名的切片。对同一文件的后续调用将产生更多的名称。 ... 如果n <= 0, Readdirnames在一个切片中返回目录中的所有名称。
代码片段:
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
names, err := file.Readdirnames(0)
if err != nil {
return err
}
fmt.Println(names)
归功于SquattingSlavInTracksuit的评论;如果可以的话,我会建议将他们的评论提升为一个答案。
使用Readdirnames递归打印目录中所有文件的完整示例
package main
import (
"fmt"
"os"
)
func main() {
path := "/path/to/your/directory"
err := readDir(path)
if err != nil {
panic(err)
}
}
func readDir(path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
names, _ := file.Readdirnames(0)
for _, name := range names {
filePath := fmt.Sprintf("%v/%v", path, name)
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
return err
}
fmt.Println(filePath)
if fileInfo.IsDir() {
readDir(filePath)
}
}
return nil
}
您可以尝试使用操作系统包中的ReadDir功能。根据文档:
ReadDir读取已命名的目录,返回按文件名排序的所有目录条目。
生成的切片包含os。DirEntry类型,它们提供了这里列出的方法。下面是一个基本的例子,列出了当前目录中所有东西的名称(包含文件夹,但没有特别标记-你可以使用IsDir()方法检查一个项目是否为文件夹):
package main
import (
"fmt"
"os"
"log"
)
func main() {
entries, err := os.ReadDir("./")
if err != nil {
log.Fatal(err)
}
for _, e := range entries {
fmt.Println(e.Name())
}
}
更简单的是,使用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
}