package df import ( "b612.me/starlog" "b612.me/staros" "b612.me/wincmd/ntfs/mft" "fmt" "github.com/spf13/cobra" "io/ioutil" "math" "os" "path/filepath" "sort" "strings" ) var Cmd = &cobra.Command{ Use: "df", Short: "分析nfts磁盘文件占用", Long: "分析nfts磁盘文件占用", Run: func(cmd *cobra.Command, args []string) { if !staros.IsRoot() { starlog.Criticalln("need administator permission to run this command") os.Exit(1) } if len(args) == 0 { os.Exit(folderSize("./")) } os.Exit(folderSize(args[0])) }, } func folderSize(path string) int { fullPath, err := filepath.Abs(path) if err != nil { starlog.Criticalln("filepath not a vaild path", path, err) return 1 } vol := filepath.VolumeName(fullPath) + `\` fmt.Println(vol) if staros.IsFile(fullPath) { fullPath = filepath.Dir(fullPath) } fmt.Println("consider folder is", fullPath) folderLists, err := ioutil.ReadDir(fullPath) if err != nil { starlog.Criticalln("read folder failed", err) return 2 } targetFolders := make(map[string]uint64) for _, v := range folderLists { if v.IsDir() { //fmt.Println(filepath.Join(fullPath, v.Name())) targetFolders[filepath.Join(fullPath, v.Name())] = 0 } } fileLists, err := mft.GetFileListsByMft(vol) if err != nil { starlog.Errorln("read mft failed", err) return 3 } var totalSize uint64 var fc1, fc2 int for _, v := range fileLists { if strings.Contains(v.Path, fullPath) { if v.IsDir { fc2++ } else { fc1++ } totalSize += v.Aszie } for k, _ := range targetFolders { if strings.Contains(v.Path, k) { targetFolders[k] += v.Aszie } } } getSize := func(size uint64) string { floatSize := float64(size) var sizeC = []string{"byte", "KB", "MB", "GB", "TB"} if floatSize < 1024 { return "" } for i := 0; i < 4; i++ { if floatSize/math.Pow(1024, float64(i+1)) < 1024 { return fmt.Sprintf("%.4f%s", floatSize/math.Pow(1024, float64(i+1)), sizeC[i+1]) } } return "" } target := sortMapByValue(targetFolders) for _, v := range target { fmt.Printf("%-20s %-10d %s\n", v.Key, v.Value, getSize(v.Value)) } fmt.Printf("%-20s %-10d %s\n", fullPath, totalSize, getSize(totalSize)) fmt.Println("file count:", fc1, "folder count:", fc2) return 0 } type Pair struct { Key string Value uint64 } type PairList []Pair func (p PairList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p PairList) Len() int { return len(p) } func (p PairList) Less(i, j int) bool { return p[i].Value < p[j].Value } func sortMapByValue(m map[string]uint64) PairList { p := make(PairList, len(m)) i := 0 for k, v := range m { p[i] = Pair{k, v} i++ } sort.Sort(p) return p }