github.com/auxten/ginkgo@v0.0.0-20220130172820-7d98ad59d232/seed/scan.go (about) 1 package seed 2 3 import ( 4 "io/fs" 5 "os" 6 "path/filepath" 7 ) 8 9 func MakeSeed(path string, blockSize int64) (*Seed, error) { 10 path = filepath.Clean(path) 11 seed := new(Seed) 12 if blockSize > 0 { 13 seed.BlockSize = blockSize 14 } else { 15 seed.BlockSize = DefaultBlockSize 16 } 17 18 if err := filepath.WalkDir(path, getWalkFunc(seed)); err != nil { 19 return nil, err 20 } 21 22 seed.Blocks[len(seed.Blocks)-1].Size = seed.TotalSize % seed.BlockSize 23 24 return seed, nil 25 } 26 27 func getWalkFunc(s *Seed) fs.WalkDirFunc { 28 var ( 29 seed = s 30 lastTotalSize int64 31 ) 32 seed.Files = make([]*File, 0) 33 seed.Blocks = make([]*Block, 0) 34 return func(path string, entry fs.DirEntry, err error) error { 35 var ( 36 fInfo fs.FileInfo 37 size int64 38 symPath string 39 ) 40 if entry == nil { 41 return err 42 } 43 if fInfo, err = entry.Info(); err != nil { 44 return err 45 } 46 //log.Debugf("%s %d", path, fInfo.Size()) 47 if err != nil { 48 return err 49 } 50 51 seed.FileCount++ 52 if entry.IsDir() { 53 size = -1 54 } else if (entry.Type() & fs.ModeSymlink) != 0 { 55 size = -2 56 if symPath, err = os.Readlink(path); err != nil { 57 return err 58 } 59 } else if entry.Type().IsRegular() { 60 size = fInfo.Size() 61 lastTotalSize = seed.TotalSize 62 seed.TotalSize += size 63 } 64 65 seed.Files = append(seed.Files, &File{ 66 mtime: fInfo.ModTime(), 67 Mode: fInfo.Mode(), 68 Size: size, 69 SymPath: symPath, 70 Path: path, 71 LocalPath: path, 72 CheckSum: nil, 73 }) 74 75 if size > 0 { 76 for int64(len(seed.Blocks))*seed.BlockSize < seed.TotalSize { 77 startOffset := int64(len(seed.Blocks))*seed.BlockSize - lastTotalSize 78 seed.Blocks = append(seed.Blocks, &Block{ 79 Size: seed.BlockSize, 80 StartFile: len(seed.Files) - 1, 81 StartOffset: startOffset, 82 Done: true, 83 }) 84 } 85 } 86 87 return nil 88 } 89 }