原文:在Golang中獲取系統(tǒng)的磁盤空間內(nèi)存占用
獲取磁盤占用情況(Linux/Mac下有效)
import (
"syscall"
)
type DiskStatus struct {
All uint64 `json:"all"`
Used uint64 `json:"used"`
Free uint64 `json:"free"`
}
// disk usage of path/disk
func DiskUsage(path string) (disk DiskStatus) {
fs := syscall.Statfs_t{}
err := syscall.Statfs(path, &fs)
if err != nil {
return
}
disk.All = fs.Blocks * uint64(fs.Bsize)
disk.Free = fs.Bfree * uint64(fs.Bsize)
disk.Used = disk.All - disk.Free
return
}
我用的MAC做開發(fā)。親測有效,很愉快的復(fù)制代碼使用去了。
當(dāng)前時間為2017年12月, go 1.9.2涉枫,距離博客時間已經(jīng)5年了,兼容性不錯
后來要編一個給windows的同事用腐螟,出問題了
先說一下愿汰,跨平臺編譯命令
# GOOS=windows GOARCH=amd64 go build
指定目標(biāo)在windows平臺困后,64位。OS有很多衬廷,不羅列了
錯誤信息
# utils/system.go:17:8: undefined: syscall.Statfs_t
# utils/system.go:18:9: undefined: syscall.Statfs
做為資深碼農(nóng)摇予,我一下子就想到這應(yīng)該是底層代碼跨平臺出了問題。為了解決這個問題吗跋,實施方案:
- 找到windows下獲取磁盤的代碼
- 條件編譯侧戴,根據(jù)目標(biāo)系統(tǒng),選擇代碼
windows下獲取磁盤空間的方法
也是在開頭的博客里找來的跌宛,但方法已做兼容性處理酗宋,否則不能通過
package utils
import "unsafe"
import (
"golang.org/x/sys/windows"
)
type DiskStatus struct {
All uint64
Used uint64
Free uint64
}
func DiskUsage(path string) (disk DiskStatus) {
h := windows.MustLoadDLL("kernel32.dll")
c := h.MustFindProc("GetDiskFreeSpaceExW")
lpFreeBytesAvailable := uint64(0)
lpTotalNumberOfBytes := uint64(0)
lpTotalNumberOfFreeBytes := uint64(0)
r1, r2, err := c.Call(uintptr(unsafe.Pointer(windows.StringToUTF16Ptr("C:"))),
uintptr(unsafe.Pointer(&lpFreeBytesAvailable)),
uintptr(unsafe.Pointer(&lpTotalNumberOfBytes)),
uintptr(unsafe.Pointer(&lpTotalNumberOfFreeBytes)))
disk.All = lpTotalNumberOfBytes
disk.Free = lpTotalNumberOfFreeBytes
disk.Used = lpFreeBytesAvailable
return
}
條件編譯
大概就是不同的目標(biāo),使用不同的代碼疆拘。 這就是跨平臺的代價吧蜕猫。
我在項目中用到的方法,創(chuàng)建了兩個文件哎迄,并在 other文件內(nèi)回右,添加非windows平臺才參加編譯的指令。
# system_other.go
// +build !windows
package utils
-----------------------------------
# system_windows.go
// +build windows
package utils
條件編譯需要前后空一行漱挚,否則無法識別,比如system_other.go文件中的條件編譯下面會空一行在寫代碼
活到老翔烁,學(xué)到老~~