使用Go获取可用磁盘空间量

时间:2013-11-20 22:33:22

标签: go diskspace

基本上我想要df -h的输出,其中包括可用空间和卷的总大小。该解决方案需要在Windows,Linux和Mac上运行,并使用Go编写。

我查看了ossyscall Go文档,但没有找到任何内容。在Windows上,甚至命令行工具也很笨拙(dir C:\)或需要提升权限(fsutil volume diskfree C:\)。当然有一种方法可以做到这一点,我还没有找到......

更新:
根据nemo的回答和邀请,我提供了cross-platform Go package来做到这一点。

3 个答案:

答案 0 :(得分:42)

在POSIX系统上,您可以使用syscall.Statfs 以当前工作目录的字节打印可用空间的示例:

import "syscall"
import "os"

var stat syscall.Statfs_t

wd, err := os.Getwd()

syscall.Statfs(wd, &stat)

// Available blocks * size per block = available space in bytes
fmt.Println(stat.Bavail * uint64(stat.Bsize))

对于Windows,您还需要使用系统调用路由。示例(source):

h := syscall.MustLoadDLL("kernel32.dll")
c := h.MustFindProc("GetDiskFreeSpaceExW")

var freeBytes int64

_, _, err := c.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(wd))),
    uintptr(unsafe.Pointer(&freeBytes)), nil, nil)

随意编写一个提供跨平台功能的软件包。 关于如何跨平台实现某些内容,请参阅build tool help page

答案 1 :(得分:5)

Minio有一个软件包(GoDoc),用于显示跨平台的磁盘使用情况,并且似乎维护得很好:

import (
        "github.com/minio/minio/pkg/disk"
        humanize "github.com/dustin/go-humanize"
)

func printUsage(path string) error {
        di, err := disk.GetInfo(path)
        if err != nil {
            return err
        }
        percentage := (float64(di.Total-di.Free)/float64(di.Total))*100
        fmt.Printf("%s of %s disk space used (%0.2f%%)\n", 
            humanize.Bytes(di.Total-di.Free), 
            humanize.Bytes(di.Total), 
            percentage,
        )
}

答案 2 :(得分:1)

这是我基于github.com/shirou/gopsutil库的df -h命令的版本

package main

import (
    "fmt"

    human "github.com/dustin/go-humanize"
    "github.com/shirou/gopsutil/disk"
)

func main() {
    formatter := "%-14s %7s %7s %7s %4s %s\n"
    fmt.Printf(formatter, "Filesystem", "Size", "Used", "Avail", "Use%", "Mounted on")

    parts, _ := disk.Partitions(true)
    for _, p := range parts {
        device := p.Mountpoint
        s, _ := disk.Usage(device)

        if s.Total == 0 {
            continue
        }

        percent := fmt.Sprintf("%2.f%%", s.UsedPercent)

        fmt.Printf(formatter,
            s.Fstype,
            human.Bytes(s.Total),
            human.Bytes(s.Used),
            human.Bytes(s.Free),
            percent,
            p.Mountpoint,
        )
    }
}