Go语言如何跨平台获取系统磁盘空间

来源:IPIPP.com作者:北京网站建设头衔:草根站长
导读:本期聚焦于小伙伴创作的《Go语言如何跨平台获取系统磁盘空间》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Go语言如何跨平台获取系统磁盘空间》有用,将其分享出去将是对创作者最好的鼓励。

Go语言作为一门支持跨平台编译的编程语言,在系统工具开发、服务器后端开发等场景中应用广泛,很多时候我们需要在程序中获取当前系统的磁盘空间信息,包括总容量、已使用容量、可用容量等。不同操作系统获取磁盘空间的底层接口存在差异,比如Linux和macOS使用statfs系统调用,Windows使用GetDiskFreeSpaceEx等Windows API,直接编写平台特定代码会导致程序兼容性差,维护成本高。

Go语言如何跨平台获取系统磁盘空间

实现思路

要实现跨平台获取磁盘空间,核心思路是利用Go语言的编译标签(build tag)和条件编译特性,为不同操作系统编写对应的实现代码,对外暴露统一的接口。这样上层调用方只需要调用统一的函数,不需要关心底层不同平台的差异,Go编译器在编译时会自动选择对应平台的代码进行编译。

统一接口定义

首先我们定义一个统一的磁盘空间信息结构体,以及获取磁盘空间的函数接口,所有平台都遵循这个接口实现。

// 磁盘空间信息结构体
type DiskSpaceInfo struct {
    Total uint64 // 总容量,单位字节
    Used  uint64 // 已使用容量,单位字节
    Free  uint64 // 可用容量,单位字节
}

// 获取指定路径所在磁盘的空间信息
// path 为需要查询的磁盘路径,比如Linux下的/,Windows下的C:
func GetDiskSpace(path string) (*DiskSpaceInfo, error)

Linux和macOS平台实现

Linux和macOS都属于类Unix系统,都支持statfs系统调用,我们可以通过syscall包调用该系统获取磁盘信息。在文件开头添加编译标签,指定该文件只在Linux和Darwin(macOS的内核名称)系统下编译。

//go:build linux || darwin

package disk

import (
    "syscall"
)

func GetDiskSpace(path string) (*DiskSpaceInfo, error) {
    var stat syscall.Statfs_t
    // 调用statfs获取磁盘信息
    if err := syscall.Statfs(path, &stat); err != nil {
        return nil, err
    }
    // 计算总容量:块数量 * 每块大小
    total := stat.Blocks * uint64(stat.Bsize)
    // 计算可用容量:可用块数量 * 每块大小
    free := stat.Bavail * uint64(stat.Bsize)
    // 已使用容量 = 总容量 - 可用容量
    used := total - free
    return &DiskSpaceInfo{
        Total: total,
        Used:  used,
        Free:  free,
    }, nil
}

Windows平台实现

Windows系统没有statfs系统调用,需要使用系统提供的GetDiskFreeSpaceEx函数获取磁盘空间信息,该函数属于kernel32.dll,我们可以通过syscall包加载对应的DLL并调用函数。同样在文件开头添加编译标签,指定该文件只在Windows系统下编译。

//go:build windows

package disk

import (
    "syscall"
    "unsafe"
)

// 加载kernel32.dll,获取GetDiskFreeSpaceEx函数
var (
    kernel32        = syscall.MustLoadDLL("kernel32.dll")
    getDiskFreeSpaceEx = kernel32.MustFindProc("GetDiskFreeSpaceExW")
)

func GetDiskSpace(path string) (*DiskSpaceInfo, error) {
    // 将路径转换为UTF16编码,Windows API需要宽字符参数
    pathPtr, err := syscall.UTF16PtrFromString(path)
    if err != nil {
        return nil, err
    }
    var (
        freeBytesAvailable     uint64
        totalNumberOfBytes     uint64
        totalNumberOfFreeBytes uint64
    )
    // 调用GetDiskFreeSpaceExW函数,注意参数需要传递指针
    ret, _, err := getDiskFreeSpaceEx.Call(
        uintptr(unsafe.Pointer(pathPtr)),
        uintptr(unsafe.Pointer(&freeBytesAvailable)),
        uintptr(unsafe.Pointer(&totalNumberOfBytes)),
        uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)),
    )
    // 返回值为0表示调用失败
    if ret == 0 {
        return nil, err
    }
    return &DiskSpaceInfo{
        Total: totalNumberOfBytes,
        Used:  totalNumberOfBytes - totalNumberOfFreeBytes,
        Free:  totalNumberOfFreeBytes,
    }, nil
}

使用示例

完成上述实现后,我们可以在其他代码中调用统一的GetDiskSpace函数获取磁盘空间信息,下面是使用示例:

package main

import (
    "fmt"
    "log"
    // 假设上面的disk包路径为your_project/disk
    "your_project/disk"
)

func main() {
    // 查询根目录所在磁盘的空间,不同平台路径不同
    var path string
    // 可以根据运行时系统选择路径,也可以由调用方传入
    // 这里简单示例,实际使用时可以自行适配
    path = "/" // Linux/macOS根目录
    // path = "C:\" // Windows C盘根目录
    info, err := disk.GetDiskSpace(path)
    if err != nil {
        log.Fatalf("获取磁盘空间失败: %v", err)
    }
    // 将字节转换为GB方便阅读,1GB = 1024*1024*1024字节
    gb := float64(1024 * 1024 * 1024)
    fmt.Printf("磁盘总容量: %.2f GBn", float64(info.Total)/gb)
    fmt.Printf("已使用容量: %.2f GBn", float64(info.Used)/gb)
    fmt.Printf("可用容量: %.2f GBn", float64(info.Free)/gb)
    // 计算使用率
    usage := float64(info.Used) / float64(info.Total) * 100
    fmt.Printf("磁盘使用率: %.2f%%n", usage)
}

注意事项

  • 传入的路径必须是存在的路径,否则会返回错误,调用前可以先判断路径是否存在。
  • 不同系统下路径格式不同,Windows路径需要包含盘符,比如C:,类Unix系统路径为/
  • 磁盘空间信息会随着系统使用情况实时变化,每次调用都会获取当前最新的信息。
  • 如果需要获取所有磁盘的信息,不同平台的遍历磁盘方式也有差异,类Unix系统可以读取/proc/mounts文件获取挂载点,Windows可以通过调用GetLogicalDrives等API获取所有盘符。

Go语言跨平台磁盘空间系统信息修改时间:2026-06-25 16:33:36

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。