2015-12-29 71 views
2

我需要遞歸地讀取一個目錄結構,但是當我讀完每個目錄的所有條目後,我還需要執行一個額外的步驟。因此,我需要編寫自己的遞歸邏輯(並且不能使用簡單的filepath.Walk例程)。但是,ioutil.ReadDirfilepath.Glob例程僅返回片。如果我推動ext4xfs的限制,並且有一個文件編號爲數十億的目錄?我期望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

ioutil.ReadDirfilepath.Glob只是方便的功能周圍閱讀目錄條目。

您可以直接使用ReaddirReaddirnames方法,如果您對供應讀取批次目錄條目的n參數> 0

對於一些基本的閱讀目錄條目,沒有必要添加的開銷一個goroutine和頻道,並且還提供了一種替代方式來返回錯誤。如果您願意,您可以隨時使用自己的goroutine和渠道模式來包裝批量調用。

+0

即使我提供一個3的例子'n',我越來越少(有時是2,有時是4)。這只是作爲諮詢價值提供的嗎? –

+0

@DustinOprea:'Readdir *'文檔說你應該返回「最多n ...」。更少的結果是可能的,但如果你能重現那個結果,那麼超過n就是一個錯誤。 – JimB

相關問題