英文:
Getting count of files in directory using Go
问题
如何获取io/ioutil.ReadDir()返回的项目数量?
我有以下代码,它可以工作,但我在想是否有更好的方法在Go语言中实现。
package main
import "io/ioutil"
import "fmt"
func main() {
files, _ := ioutil.ReadDir("/Users/dgolliher/Dropbox/INBOX")
var count int
for _, f := range files {
fmt.Println(f.Name())
count++
}
fmt.Println(count)
}
第8-12行似乎太冗长了,只是为了计算ReadDir的结果数量,但我找不到正确的语法来在不迭代范围的情况下获取计数。请帮忙解决一下?
英文:
How might I get the count of items returned by io/ioutil.ReadDir()?
I have this code, which works, but I have to think isn't the RightWay(tm) in Go.
package main
import "io/ioutil"
import "fmt"
func main() {
files,_ := ioutil.ReadDir("/Users/dgolliher/Dropbox/INBOX")
var count int
for _, f := range files {
fmt.Println(f.Name())
count++
}
fmt.Println(count)
}
Lines 8-12 seem like way too much to go through to just count the results of ReadDir, but I can't find the correct syntax to get the count without iterating over the range. Help?
答案1
得分: 20
在http://blog.golang.org/go-slices-usage-and-internals中找到了答案。
package main
import "io/ioutil"
import "fmt"
func main() {
files,_ := ioutil.ReadDir("/Users/dgolliher/Dropbox/INBOX")
fmt.Println(len(files))
}
请注意,这是一个Go语言的代码示例,它使用了ioutil
包来读取指定目录下的文件,并打印出文件数量。
英文:
Found the answer in http://blog.golang.org/go-slices-usage-and-internals
package main
import "io/ioutil"
import "fmt"
func main() {
files,_ := ioutil.ReadDir("/Users/dgolliher/Dropbox/INBOX")
fmt.Println(len(files))
}
答案2
得分: 8
ReadDir返回按文件名排序的目录条目列表,因此不仅仅是文件。这是一个小函数,用于只获取文件计数(而不是目录)的人:
func fileCount(path string) (int, error){
i := 0
files, err := ioutil.ReadDir(path)
if err != nil {
return 0, err
}
for _, file := range files {
if !file.IsDir() {
i++
}
}
return i, nil
}
英文:
ReadDir returns a list of directory entries sorted by filename, so it is not just files. Here is a little function for those wanting to get a count of files only (and not dirs):
func fileCount(path string) (int, error){
i := 0
files, err := ioutil.ReadDir(path)
if err != nil {
return 0, err
}
for _, file := range files {
if !file.IsDir() {
i++
}
}
return i, nil
}
答案3
得分: 6
从Go 1.16(2021年2月)开始,更好的选择是os.ReadDir
:
package main
import "os"
func main() {
d, e := os.ReadDir(".")
if e != nil {
panic(e)
}
println(len(d))
}
os.ReadDir
返回的是fs.DirEntry
而不是fs.FileInfo
,这意味着Size
和ModTime
方法被省略了,如果你只需要一个条目计数,这样的处理方式更高效。
https://golang.org/pkg/os#ReadDir
英文:
Starting with Go 1.16 (Feb 2021), a better option is os.ReadDir
:
package main
import "os"
func main() {
d, e := os.ReadDir(".")
if e != nil {
panic(e)
}
println(len(d))
}
os.ReadDir
returns fs.DirEntry
instead of fs.FileInfo
, which means that
Size
and ModTime
methods are omitted, making the process more efficient if
you just need an entry count.
答案4
得分: 1
如果你想获取所有文件(非递归),你可以使用len(files)。如果你只需要获取文件而不包括文件夹和隐藏文件,只需遍历它们并增加一个计数器。请不要忽略错误。
英文:
If you wanna get all files (not recursive) you can use len(files). If you need to just get the files without folders and hidden files just loop over them and increase a counter. And please don’t ignore errors
答案5
得分: 0
通过查看ioutil.ReadDir的代码,你会发现它调用了os.File.Readdir()
然后对文件进行排序。
如果只是计数的话,你不需要进行排序,所以最好直接调用os.File.Readdir()
。你可以简单地复制并粘贴这个函数,然后移除排序部分。但是我发现f.Readdirnames(-1)
比f.Readdir(-1)
要快得多。对于包含2808个项目的/usr/bin/
目录,运行时间几乎减少了一半(16毫秒对比35毫秒)。所以,总结一下,可以用以下示例代码来实现:
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Open(os.Args[1])
if err != nil {
panic(err)
}
list, err := f.Readdirnames(-1)
f.Close()
if err != nil {
panic(err)
}
fmt.Println(len(list))
}
英文:
By looking at the code of ioutil.ReadDir
func ReadDir(dirname string) ([]fs.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
}
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
return list, nil
}
you would realize that it calls os.File.Readdir()
then sorts the files.
In case of counting it, you don't need to sort, so you are better off calling os.File.Readdir()
directly.
You can simply copy and paste this function then remove the sort.
But I did find out that f.Readdirnames(-1)
is much faster than f.Readdir(-1)
.
Running time is almost half for /usr/bin/
with 2808 items (16ms vs 35ms).
So to summerize it in an example:
package main
import (
"fmt"
"os"
)
func main() {
f, err := os.Open(os.Args[1])
if err != nil {
panic(err)
}
list, err := f.Readdirnames(-1)
f.Close()
if err != nil {
panic(err)
}
fmt.Println(len(list))
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论