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

Ric*_*ith 22 diskspace go

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

我已经通过看ossyscall转到文件,并没有发现任何东西.在Windows上,甚至命令行工具都是awkward(dir C:\)或需要提升权限(fsutil volume diskfree C:\).当然有一种方法可以做到这一点,我还没有找到...

更新:
根据nemo的回答和邀请,我提供了一个跨平台的Go包来完成这个任务.

nem*_*emo 45

在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))
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

随意编写一个提供跨平台功能的软件包.关于如何跨平台实现某些功能,请参阅构建工具帮助页面.

  • "在POSIX系统上你可以使用syscall.Statfs"不幸的是,这不是一个符合POSIX标准的系统调用.符合POSIX的呼叫是"statvfs".Statfs提供了有关不同*NIX操作系统的不同信息.为什么围棋制造商选择实施非POSIX兼容版本超出我的范围. (4认同)
  • 感谢您的详细信息.我已经更新了我的问题,以包含指向我的包的链接. (2认同)
  • 从包文档中:“已弃用:此包已被锁定。调用者应使用 golang.org/x/sys 存储库中的相应包。https://golang.org/pkg/syscall/#Statfs (2认同)

小智 9

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,
        )
}
Run Code Online (Sandbox Code Playgroud)

  • go: 找到模块 github.com/minio/minio@upgrade (v0.0.0-20230424202818-8fd07bcd51cf),但不包含包 github.com/minio/minio/pkg/disk (2认同)

Rom*_*kin 5

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

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,
        )
    }
}

Run Code Online (Sandbox Code Playgroud)