使用Go语言获取可用磁盘空间的数量。

huangapple go评论86阅读模式
英文:

Get amount of free disk space using Go

问题

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

我已经查阅了Go语言的ossyscall文档,但没有找到相关内容。在Windows上,即使是命令行工具也要么很麻烦(dir C:\),要么需要提升权限(fsutil volume diskfree C:\)。肯定有一种我还没有发现的方法...

更新:
根据nemo的答案和邀请,我提供了一个跨平台的Go包来实现这个功能。

英文:

Basically I want the output of df -h, which includes both the free space and the total size of the volume. The solution needs to work on Windows, Linux, and Mac and be written in Go.

I have looked through the os and syscall Go documentation and haven't found anything. On Windows, even command line utils are either awkward (dir C:\) or need elevated privileges (fsutil volume diskfree C:\). Surely there is a way to do this that I haven't found yet...

UPDATE:
Per nemo's answer and invitation, I have provided a cross-platform Go package that does this.

答案1

得分: 73

在POSIX系统上,您可以使用sys.unix.Statfs。以下是打印当前工作目录中可用空间(以字节为单位)的示例代码:

import "golang.org/x/sys/unix"
import "os"

var stat unix.Statfs_t

wd, err := os.Getwd()

unix.Statfs(wd, &stat)

// 可用块数 * 每块的大小 = 可用空间(以字节为单位)
fmt.Println(stat.Bavail * uint64(stat.Bsize))

对于Windows系统,您也需要使用syscall。以下是一个示例代码(来源,已更新以匹配new sys/windows package):

import "golang.org/x/sys/windows"

var freeBytesAvailable uint64
var totalNumberOfBytes uint64
var totalNumberOfFreeBytes uint64

err := windows.GetDiskFreeSpaceEx(windows.StringToUTF16Ptr("C:"),
    &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes)

您可以编写一个跨平台的功能包来提供这个功能。有关如何实现跨平台功能的详细信息,请参阅构建工具帮助页面

英文:

On POSIX systems you can use sys.unix.Statfs.
Example of printing free space in bytes of current working directory:

import "golang.org/x/sys/unix"
import "os"

var stat unix.Statfs_t

wd, err := os.Getwd()

unix.Statfs(wd, &stat)

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

For Windows you need to go the syscall route as well. Example (source, updated to match new sys/windows package):

import "golang.org/x/sys/windows"

var freeBytesAvailable uint64
var totalNumberOfBytes uint64
var totalNumberOfFreeBytes uint64

err := windows.GetDiskFreeSpaceEx(windows.StringToUTF16Ptr("C:"),
	&freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes)

Feel free to write a package that provides the functionality cross-platform.
On how to implement something cross-platform, see the build tool help page.

答案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,
	)
}
英文:

Minio has a package (GoDoc) to show disk usage that is cross platform, and seems to be well maintained:

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

答案3

得分: 8

这是基于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, "文件系统", "大小", "已用", "可用", "使用%", "挂载点")

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

英文:

Here is my version of the df -h command based on github.com/shirou/gopsutil library

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

huangapple
  • 本文由 发表于 2013年11月21日 06:33:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/20108520.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定