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.
121 lines
2.7 KiB
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
|
|
}
|