|
- package rclone
-
- import (
- "context"
- "io"
-
- "github.com/rclone/rclone/fs"
- stgtypes "gitlink.org.cn/cloudream/jcs-pub/common/pkgs/storage/types"
- jcstypes "gitlink.org.cn/cloudream/jcs-pub/common/types"
- )
-
- type DirReader struct {
- fs fs.Fs
- rootPath string
- // ReadDir函数传递进来的path参数
- rootJPath jcstypes.JPath
- init bool
- curEntries []DirEntry
- }
-
- func NewDirReader(fs fs.Fs, rootPath string, rootJPath jcstypes.JPath) *DirReader {
- return &DirReader{
- fs: fs,
- rootPath: rootPath,
- rootJPath: rootJPath,
- }
- }
-
- func (r *DirReader) Next() (stgtypes.DirEntry, error) {
- e, err := r.NextRaw()
- if err != nil {
- return stgtypes.DirEntry{}, err
- }
-
- eFullJPath := r.rootJPath.ConcatNew(e.Dir)
- // 如果根路径就是一个文件,那么Name就为空
- if e.Name != "" {
- eFullJPath.Push(e.Name)
- }
-
- switch e2 := e.Entry.(type) {
- case fs.Object:
- return stgtypes.DirEntry{
- Path: eFullJPath,
- Size: e2.Size(),
- ModTime: e2.ModTime(context.Background()),
- IsDir: false,
- }, nil
-
- default:
- return stgtypes.DirEntry{
- Path: eFullJPath,
- Size: 0,
- ModTime: e2.ModTime(context.Background()),
- IsDir: true,
- }, nil
- }
- }
-
- func (r *DirReader) NextRaw() (DirEntry, error) {
- if !r.init {
- info, err := r.fs.NewObject(context.Background(), r.rootPath)
- if err == nil {
- r.init = true
- return DirEntry{
- Dir: jcstypes.JPath{},
- Entry: info,
- Name: "",
- }, nil
- }
-
- if err != fs.ErrorIsDir {
- return DirEntry{}, err
- }
-
- es, err := r.fs.List(context.Background(), r.rootPath)
- if err != nil {
- return DirEntry{}, err
- }
-
- for _, e := range es {
- r.curEntries = append(r.curEntries, DirEntry{
- Dir: jcstypes.JPath{},
- Entry: e,
- Name: BaseName(e.Remote()),
- })
- }
-
- r.init = true
- }
- if len(r.curEntries) == 0 {
- return DirEntry{}, io.EOF
- }
-
- entry := r.curEntries[0]
- r.curEntries = r.curEntries[1:]
-
- _, isDir := entry.Entry.(fs.Directory)
- if isDir {
- dirPath := Join(r.rootPath, entry.Dir.String(), entry.Name)
- es, err := r.fs.List(context.Background(), dirPath)
- if err != nil {
- return DirEntry{}, err
- }
-
- // 多个entry对象共享同一个JPath对象,但因为不会修改JPath,所以没问题
- dir := entry.Dir.Clone()
- dir.Push(entry.Name)
- for _, e := range es {
- r.curEntries = append(r.curEntries, DirEntry{
- Dir: dir,
- Entry: e,
- Name: BaseName(e.Remote()),
- })
- }
- }
-
- return entry, nil
- }
-
- func (r *DirReader) Close() {
-
- }
-
- type DirEntry struct {
- Dir jcstypes.JPath
- Entry fs.DirEntry
- Name string
- }
|