| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- package ftp
- import (
- "path"
- )
- // Walker traverses the directory tree of a remote FTP server
- type Walker struct {
- serverConn *ServerConn
- root string
- cur *item
- stack []*item
- descend bool
- }
- type item struct {
- path string
- entry *Entry
- err error
- }
- // Next advances the Walker to the next file or directory,
- // which will then be available through the Path, Stat, and Err methods.
- // It returns false when the walk stops at the end of the tree.
- func (w *Walker) Next() bool {
- // check if we need to init cur, maybe this should be inside Walk
- if w.cur == nil {
- w.cur = &item{
- path: w.root,
- entry: &Entry{
- Type: EntryTypeFolder,
- },
- }
- }
- if w.descend && w.cur.entry.Type == EntryTypeFolder {
- entries, err := w.serverConn.List(w.cur.path)
- // an error occurred, drop out and stop walking
- if err != nil {
- w.cur.err = err
- return false
- }
- for _, entry := range entries {
- if entry.Name == "." || entry.Name == ".." {
- continue
- }
- item := &item{
- path: path.Join(w.cur.path, entry.Name),
- entry: entry,
- }
- w.stack = append(w.stack, item)
- }
- }
- if len(w.stack) == 0 {
- return false
- }
- // update cur
- i := len(w.stack) - 1
- w.cur = w.stack[i]
- w.stack = w.stack[:i]
- // reset SkipDir
- w.descend = true
- return true
- }
- // SkipDir tells the Next function to skip the currently processed directory
- func (w *Walker) SkipDir() {
- w.descend = false
- }
- // Err returns the error, if any, for the most recent attempt by Next to
- // visit a file or a directory. If a directory has an error, the walker
- // will not descend in that directory
- func (w *Walker) Err() error {
- return w.cur.err
- }
- // Stat returns info for the most recent file or directory
- // visited by a call to Next.
- func (w *Walker) Stat() *Entry {
- return w.cur.entry
- }
- // Path returns the path to the most recent file or directory
- // visited by a call to Next. It contains the argument to Walk
- // as a prefix; that is, if Walk is called with "dir", which is
- // a directory containing the file "a", Path will return "dir/a".
- func (w *Walker) Path() string {
- return w.cur.path
- }
|