美文网首页
GO golang 获取磁盘空间 条件编译

GO golang 获取磁盘空间 条件编译

作者: 勤劳一沙鸥 | 来源:发表于2017-12-05 18:23 被阅读907次

    原文:在Golang中获取系统的磁盘空间内存占用

    获取磁盘占用情况(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
    

    做为资深码农,我一下子就想到这应该是底层代码跨平台出了问题。为了解决这个问题,实施方案:

    1. 找到windows下获取磁盘的代码
    2. 条件编译,根据目标系统,选择代码

    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文件中的条件编译下面会空一行在写代码
    活到老,学到老~~

    相关文章

      网友评论

          本文标题:GO golang 获取磁盘空间 条件编译

          本文链接:https://www.haomeiwen.com/subject/fwicixtx.html