我需要遞歸地讀取一個目錄結構,但是當我讀完每個目錄的所有條目後,我還需要執行一個額外的步驟。因此,我需要編寫自己的遞歸邏輯(並且不能使用簡單的filepath.Walk
例程)。但是,ioutil.ReadDir
和filepath.Glob
例程僅返回片。如果我推動ext4或xfs的限制,並且有一個文件編號爲數十億的目錄?我期望golang有一個函數,可以在信道上而不是排序的片上返回未排序的os.FileInfo
(或更好的原始字符串)系列。在這種情況下我們如何有效地讀取文件條目?在一個有很多條目的目錄中有效地列出文件
所有上面提到的功能似乎OS/dir_unix.go依靠readdirnames
,並且,出於某種原因,它只是使一個數組時,它看起來像它會一直容易釀出gothread,並將這些值推入一個通道。這樣做可能有合理的邏輯,但不清楚它是什麼。我是Go新手,所以我也很容易錯過一些對其他人都很明顯的原則。
這是源代碼,爲了方便:
func (f *File) readdirnames(n int) (names []string, err error) {
// If this file has no dirinfo, create one.
if f.dirinfo == nil {
f.dirinfo = new(dirInfo)
// The buffer must be at least a block long.
f.dirinfo.buf = make([]byte, blockSize)
}
d := f.dirinfo
size := n
if size <= 0 {
size = 100
n = -1
}
names = make([]string, 0, size) // Empty with room to grow.
for n != 0 {
// Refill the buffer if necessary
if d.bufp >= d.nbuf {
d.bufp = 0
var errno error
d.nbuf, errno = fixCount(syscall.ReadDirent(f.fd, d.buf))
if errno != nil {
return names, NewSyscallError("readdirent", errno)
}
if d.nbuf <= 0 {
break // EOF
}
}
// Drain the buffer
var nb, nc int
nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
d.bufp += nb
n -= nc
}
if n >= 0 && len(names) == 0 {
return names, io.EOF
}
return names, nil
}
即使我提供一個3的例子'n',我越來越少(有時是2,有時是4)。這只是作爲諮詢價值提供的嗎? –
@DustinOprea:'Readdir *'文檔說你應該返回「最多n ...」。更少的結果是可能的,但如果你能重現那個結果,那麼超過n就是一個錯誤。 – JimB