获取磁盘占用情况(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做开发。亲测有效,很愉快的复制代码使用去了。
当前时间为2017年12月, go 1.9.2,距离博客时间已经5年了,兼容性不错
后来要编一个给windows的同事用,出问题了
先说一下,跨平台编译命令
# GOOS=windows GOARCH=amd64 go build
指定目标在windows平台,64位。OS有很多,不罗列了
错误信息
# utils/system.go:17:8: undefined: syscall.Statfs_t
# utils/system.go:18:9: undefined: syscall.Statfs
做为资深码农,我一下子就想到这应该是底层代码跨平台出了问题。为了解决这个问题,实施方案:
- 找到windows下获取磁盘的代码
- 条件编译,根据目标系统,选择代码
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
}
条件编译
大概就是不同的目标,使用不同的代码。 这就是跨平台的代价吧。
我在项目中用到的方法,创建了两个文件,并在 other文件内,添加非windows平台才参加编译的指令。
# system_other.go
// +build !windows
package utils
-----------------------------------
# system_windows.go
// +build windows
package utils
条件编译需要前后空一行,否则无法识别,比如system_other.go文件中的条件编译下面会空一行在写代码
活到老,学到老~~