package putp import ( "fmt" "os" "path/filepath" "time" "github.com/inhies/go-bytesize" cliapi "gitlink.org.cn/cloudream/jcs-pub/client/sdk/api/v1" "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/iterator" jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types" ) type FileIterator struct { absRootPath string jpathRoot jcstypes.JPath init bool curEntries []dirEntry lastStartTime time.Time totalSize int64 fileCount int } func (i *FileIterator) MoveNext() (*cliapi.UploadingObject, error) { if !i.init { es, err := os.ReadDir(i.absRootPath) if err != nil { return nil, err } for _, e := range es { i.curEntries = append(i.curEntries, dirEntry{ dir: jcstypes.JPath{}, entry: e, }) } i.init = true } for { if len(i.curEntries) == 0 { return nil, iterator.ErrNoMoreItem } entry := i.curEntries[0] i.curEntries = i.curEntries[1:] if entry.entry.IsDir() { es, err := os.ReadDir(filepath.Join(i.absRootPath, entry.dir.OSString(), entry.entry.Name())) if err != nil { return nil, err } // 多个entry对象共享同一个JPath对象,但因为不会修改JPath,所以没问题 dir := entry.dir.Clone() dir.Push(entry.entry.Name()) for _, e := range es { i.curEntries = append(i.curEntries, dirEntry{ dir: dir, entry: e, }) } continue } file, err := os.Open(filepath.Join(i.absRootPath, entry.dir.OSString(), entry.entry.Name())) if err != nil { return nil, err } info, err := file.Stat() if err != nil { return nil, err } i.totalSize += info.Size() i.fileCount++ jpath := i.jpathRoot.ConcatNew(entry.dir) path := jpath.PushNew(entry.entry.Name()).String() now := time.Now() if !i.lastStartTime.IsZero() { dt := now.Sub(i.lastStartTime) fmt.Printf("\t%v\n", dt) } i.lastStartTime = now fmt.Printf("%v\t%v", path, bytesize.ByteSize(info.Size())) return &cliapi.UploadingObject{ Path: path, File: file, }, nil } } func (i *FileIterator) Close() { } type dirEntry struct { dir jcstypes.JPath entry os.DirEntry }