Getting count of files in directory using Go

huangapple go评论86阅读模式
英文:

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,这意味着SizeModTime方法被省略了,如果你只需要一个条目计数,这样的处理方式更高效。

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.

https://golang.org/pkg/os#ReadDir

答案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))
}

huangapple
  • 本文由 发表于 2014年6月8日 10:37:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/24102512.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定