You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/df/df.go

121 lines
2.7 KiB
Go

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
}