Go语言实现跨平台获取磁盘空间信息

Go语言实现跨平台获取磁盘空间信息

本文详细介绍了如何使用go语言在不同操作系统linux/macos和windows)下获取磁盘的可用空间和总空间信息。通过`golang.org/x/sys/unix`和`golang.org/x/sys/windows`包,提供了针对posix和windows系统的具体实现代码,并探讨了如何利用go的构建约束机制来构建一个跨平台的解决方案,帮助开发者便捷地获取类似于`df -h`的磁盘使用报告。

在开发跨平台应用程序时,获取系统磁盘的可用空间和总空间信息是一个常见的需求,类似于在Linux/macOS上执行df -h命令。Go语言本身的标准库并未直接提供一个统一的跨平台API来完成此任务,但通过利用特定操作系统的系统调用包,我们可以实现这一功能。

1. 在POSIX系统(Linux/macOS)上获取磁盘空间

对于基于POSIX标准的系统,如Linux和macOS,我们可以使用golang.org/x/sys/unix包中的Statfs函数来获取文件系统统计信息。这个函数会填充一个Statfs_t结构体,其中包含了我们所需的大部分磁盘信息。

Statfs_t结构体中的关键字段包括:

Bsize:文件系统块的大小(字节)。Blocks:文件系统中的总块数。Bfree:文件系统中可用块的总数(包括为超级用户保留的块)。Bavail:非超级用户可用的块数。

通常,我们关注的是非超级用户可用的空间,即Bavail。

立即学习“go语言免费学习笔记(深入)”;

以下是一个获取当前工作目录所在文件系统可用空间(字节)的示例:

package mainimport (    "fmt"    "log"    "os"    "golang.org/x/sys/unix")func main() {    var stat unix.Statfs_t    // 获取当前工作目录    wd, err := os.Getwd()    if err != nil {        log.Fatalf("获取当前工作目录失败: %v", err)    }    // 调用Statfs获取文件系统信息    err = unix.Statfs(wd, &stat)    if err != nil {        log.Fatalf("调用Statfs失败: %v", err)    }    // 计算可用空间:非超级用户可用块数 * 每块大小    availableSpaceBytes := stat.Bavail * uint64(stat.Bsize)    // 计算总空间:总块数 * 每块大小    totalSpaceBytes := stat.Blocks * uint64(stat.Bsize)    // 计算已用空间    usedSpaceBytes := totalSpaceBytes - (stat.Bfree * uint64(stat.Bsize)) // Bfree 是所有可用块,包含root保留的    fmt.Printf("路径: %s", wd)    fmt.Printf("总空间: %d 字节 (%.2f GB)", totalSpaceBytes, float64(totalSpaceBytes)/(1024*1024*1024))    fmt.Printf("可用空间: %d 字节 (%.2f GB)", availableSpaceBytes, float64(availableSpaceBytes)/(1024*1024*1024))    fmt.Printf("已用空间: %d 字节 (%.2f GB)", usedSpaceBytes, float64(usedSpaceBytes)/(1024*1024*1024))}

注意事项:

Reclaim.ai Reclaim.ai

为优先事项创建完美的时间表

Reclaim.ai 90 查看详情 Reclaim.ai golang.org/x/sys/unix是一个外部包,需要通过go get golang.org/x/sys/unix进行安装。Bavail是针对非root用户可用的空间,这通常是用户最关心的“可用”空间。

2. 在Windows系统上获取磁盘空间

在Windows平台上,我们需要使用golang.org/x/sys/windows包中的GetDiskFreeSpaceEx函数。这个函数能够提供指定驱动器的可用字节数、总字节数以及总的可用字节数。

GetDiskFreeSpaceEx函数的签名如下:func GetDiskFreeSpaceEx(lpDirectoryName *uint16, lpFreeBytesAvailable *uint64, lpTotalNumberOfBytes *uint64, lpTotalNumberOfFreeBytes *uint64) (err error)

参数说明:

lpDirectoryName:指向一个以null结尾的字符串,指定要获取信息的磁盘或UNC路径。例如,”C:”。在Go中,需要将其转换为UTF16指针。lpFreeBytesAvailable:接收调用用户可用的字节数。lpTotalNumberOfBytes:接收磁盘的总字节数。lpTotalNumberOfFreeBytes:接收磁盘上所有用户可用的总字节数。

以下是一个获取C盘磁盘空间信息的示例:

package mainimport (    "fmt"    "log"    "syscall"    "golang.org/x/sys/windows")func main() {    var freeBytesAvailable uint64    var totalNumberOfBytes uint64    var totalNumberOfFreeBytes uint64 // 所有用户可用的总字节数    // 指定要查询的驱动器路径,并转换为UTF16指针    drive := "C:"    drivePtr, err := syscall.UTF16PtrFromString(drive)    if err != nil {        log.Fatalf("转换驱动器路径失败: %v", err)    }    // 调用GetDiskFreeSpaceEx    err = windows.GetDiskFreeSpaceEx(drivePtr,        &freeBytesAvailable,       // 当前用户可用的字节数        &totalNumberOfBytes,      // 磁盘总字节数        &totalNumberOfFreeBytes) // 磁盘上所有用户可用的总字节数    if err != nil {        log.Fatalf("调用GetDiskFreeSpaceEx失败: %v", err)    }    fmt.Printf("驱动器: %s", drive)    fmt.Printf("总空间: %d 字节 (%.2f GB)", totalNumberOfBytes, float64(totalNumberOfBytes)/(1024*1024*1024))    fmt.Printf("当前用户可用空间: %d 字节 (%.2f GB)", freeBytesAvailable, float64(freeBytesAvailable)/(1024*1024*1024))    fmt.Printf("所有用户可用空间: %d 字节 (%.2f GB)", totalNumberOfFreeBytes, float64(totalNumberOfFreeBytes)/(1024*1024*1024))    fmt.Printf("已用空间: %d 字节 (%.2f GB)", totalNumberOfBytes-totalNumberOfFreeBytes, float64(totalNumberOfBytes-totalNumberOfFreeBytes)/(1024*1024*1024))}

注意事项:

golang.org/x/sys/windows是一个外部包,需要通过go get golang.org/x/sys/windows进行安装。syscall.UTF16PtrFromString用于将Go字符串转换为Windows API所需的UTF16指针。

3. 构建跨平台的磁盘空间获取功能

为了实现一个统一的跨平台API来获取磁盘空间,我们可以利用Go语言的构建约束(Build Constraints)机制。通过在文件名或文件顶部添加特定的注释,Go编译器会根据目标操作系统选择性地编译不同的源文件。

构建约束示例:

//go:build windows:仅在Windows系统上编译。//go:build unix:仅在类Unix系统(Linux, macOS, FreeBSD等)上编译。

我们可以创建一个公共接口(例如,一个名为DiskUsage的结构体或函数),然后为每个操作系统提供一个具体的实现文件。

示例文件结构:

disk_usage/├── disk_usage.go       // 定义公共接口和结构体├── disk_usage_unix.go  // Unix/Linux/macOS 实现└── disk_usage_windows.go // Windows 实现

disk_usage.go (公共接口定义):

package disk_usageimport "fmt"// DiskStatus 存储磁盘使用情况信息type DiskStatus struct {    Total      uint64 // 总空间 (字节)    Free       uint64 // 可用空间 (字节)    Used       uint64 // 已用空间 (字节)    FreeForUser uint64 // 对当前用户可用的空间 (字节)}// GetDiskUsage 获取指定路径的磁盘使用情况// 此函数将在不同的操作系统中被具体实现func GetDiskUsage(path string) (*DiskStatus, error) {    // 这是一个占位符,实际实现将在特定OS文件中    return nil, fmt.Errorf("未实现GetDiskUsage函数")}

disk_usage_unix.go (Unix系统实现):

//go:build unixpackage disk_usageimport (    "fmt"    "golang.org/x/sys/unix")func GetDiskUsage(path string) (*DiskStatus, error) {    var stat unix.Statfs_t    err := unix.Statfs(path, &stat)    if err != nil {        return nil, fmt.Errorf("获取Unix磁盘状态失败: %w", err)    }    total := stat.Blocks * uint64(stat.Bsize)    free := stat.Bfree * uint64(stat.Bsize) // 包括root保留的    freeForUser := stat.Bavail * uint64(stat.Bsize)    used := total - free // 粗略计算,可能不完全精确,因为文件系统开销    return &DiskStatus{        Total:      total,        Free:       free,        Used:       used,        FreeForUser: freeForUser,    }, nil}

disk_usage_windows.go (Windows系统实现):

//go:build windowspackage disk_usageimport (    "fmt"    "syscall"    "golang.org/x/sys/windows")func GetDiskUsage(path string) (*DiskStatus, error) {    var freeBytesAvailable uint64    var totalNumberOfBytes uint64    var totalNumberOfFreeBytes uint64    // Windows路径需要以反斜杠结尾,例如 "C:"    if len(path) > 0 && path[len(path)-1] != '' {        path += ""    }    drivePtr, err := syscall.UTF16PtrFromString(path)    if err != nil {        return nil, fmt.Errorf("转换Windows驱动器路径失败: %w", err)    }    err = windows.GetDiskFreeSpaceEx(drivePtr,        &freeBytesAvailable,        &totalNumberOfBytes,        &totalNumberOfFreeBytes)    if err != nil {        return nil, fmt.Errorf("获取Windows磁盘状态失败: %w", err)    }    used := totalNumberOfBytes - totalNumberOfFreeBytes    return &DiskStatus{        Total:      totalNumberOfBytes,        Free:       totalNumberOfFreeBytes, // 所有用户可用的总字节数        Used:       used,        FreeForUser: freeBytesAvailable,   // 当前用户可用的字节数    }, nil}

通过这种方式,当你在不同的操作系统上编译你的Go程序时,Go工具链会自动选择正确的disk_usage_*.go文件进行编译,从而提供一个统一的GetDiskUsage函数接口。

总结

Go语言虽然没有提供一个开箱即用的跨平台API来获取磁盘空间信息,但通过利用其强大的golang.org/x/sys系列包和灵活的构建约束机制,我们可以轻松地为不同操作系统编写特定的实现,并将其封装成一个统一的、易于使用的跨平台功能。这不仅提高了代码的可维护性,也使得Go程序能够更好地适应多样化的运行环境。对于更复杂的磁盘操作,可以考虑使用或参考已有的开源库,例如在问题描述中提到的github.com/ricochet2200/go-disk-usage,它已经实现了这种跨平台逻辑。

以上就是Go语言实现跨平台获取磁盘空间信息的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1003803.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月1日 23:40:41
下一篇 2025年12月1日 23:41:02

相关推荐

  • 比特币实时行情价格查询渠道汇总,平台与网站结合使用指南

    对于刚接触比特币的新手来说,实时掌握行情非常重要。结合行情网站和主流交易所,可以更全面了解市场动态并便于后续操作。以下为比特币行情查询的渠道推荐及使用指南。 通过交易所查看比特币行情 1、币安(Binance):提供实时K线图、涨跌幅、深度图等数据,新手可在交易界面直接查看行情,同时进行交易和质押操…

    2025年12月9日 好文分享
    000
  • 比特币价格实时查询渠道推荐,一站查看所有币种行情

    一、比特币主流交易所实时行情参考 1、币安(Binance):拥有丰富的K线图、深度图及交易量数据,新手可以直接在界面查看比特币价格,同时进行质押和账户管理操作。 2、欧易OKX(OKX):提供详细的行情板块,包括实时涨跌幅和交易量,新手可快速掌握价格变化,方便跟踪市场趋势。 3、火币(HTX):支…

    2025年12月9日 好文分享
    000
  • XRP和Solana ETF延期引发市场波动,十月前继续持有还是退出?

    近期xrp和solana的etf上市计划再次被推迟,市场随之出现波动。许多投资者在权衡是否继续持有或提前退出,尤其是短期资金管理者更为谨慎。etf延期不仅影响价格,还反映了监管审批的不确定性,这对市场情绪形成直接冲击。 对于想要实时跟踪市场动态的投资者,可以通过 币安(Binance) 或 欧易OK…

    2025年12月9日
    000
  • Bio Protocol(BIO币)价格预测:2025、2026、2027-2030年

    目录 项目定位核心技术BIO代币经济学Bio Protocol(BIO)价格预测Bio Protocol 价格预测:RSI 和 MACD 确认Bio Protocol 价格预测:超级趋势和 DMI 强度生物协议(BIO)2025-2030年价格目标Bio Protocol(BIO)2026年价格预测…

    2025年12月9日 好文分享
    000
  • 什么是现货XRP ETF?与比特币ETF有何不同?

    现货XRP ETF是跟踪XRP价格并直接持有实物资产的基金,与比特币ETF在资产种类、市场接受度、风险波动和监管环境方面存在差异,投资者可通过交易所如币安开户、充值、购买份额参与投资。 现货XRP ETF的定义 现货XRP ETF是一种跟踪XRP(瑞波币)价格的交易所交易基金。它允许投资者在股票市场…

    2025年12月9日
    000
  • otc交易和c2c交易的区别及其交易软件一览

    场外交易(OTC)和C2C交易是加密货币领域两种常见的交易模式。尽管它们都涉及买卖双方直接交易,但两者在交易方式、安全保障和适用场景等方面存在显著差异。本文将深入探讨OTC交易和C2C交易的区别,并提供一些常用的交易软件的概览,帮助读者更好地了解和选择适合自己的交易方式。 常用的OTC/C2C交易软…

    2025年12月9日
    000
  • 如何使用布林带识别加密市场突破与趋势?完整操作指南

    目录 什么是布林通道?布林通道的结构了解上轨、下轨和中轨如何针对不同的交易风格调整布林带设定区间波动加密货币市场的布林带反弹策略如何利用布林带收缩来发现趋势突破如何结合布林带与RSI 和MACD 以获得更强的交易讯号设置细节:为何要结合技术指标?结论 在当今瞬息万变的金融世界中,加密货币已不仅仅是一…

    2025年12月9日 好文分享
    000
  • 币安Binance中文版App下载

    币安Binance中文版APP官方下载 币安交易所官网: 币安官方app下载: 币安作为全球领先的数字货币交易平台,其中文版APP为国内用户提供了更为友好的操作界面和完善的功能体验。获取最新的币安APP,请务必通过币安官网入口进行下载安装,以确保版本安全与功能完整。 币安账户注册与实名认证流程 新手…

    2025年12月9日 好文分享
    000
  • 以太坊创历史新高!这7种隐藏的山寨币具有爆发性潜力!

    目录 MAGACOIN FINANCE — 2025 年最值得购买的山寨币Chainlink (LINK) — 为区块链连接提供动力Arbitrum(ARB)——Layer 2 的崛起Hedera (HBAR) — 企业采用VeChain(VET)——供应链实用程序Kaspa (KAS) — 为速度…

    2025年12月9日 好文分享
    000
  • AriaAI(ARIA币)是什么?怎么样?ARIA代币经济与空投领取指南

    什么是 AriaAI AriaAI 是一项前沿的游戏开发与发行创新项目,灵感来源于迪士尼式的沉浸式体验与人工智能技术,专注于打造自有IP驱动的互动娱乐内容。它标志着将Web2级别的高品质游戏设计与运营标准成功引入Web3领域的重要一步。 通过深度融合AI技术,ARIA正在构建一个充满生命力、可自我演…

    2025年12月9日 好文分享
    000
  • Solana ETF何时获得批准?Solana ETF是什么?它如何运作?

    Solana ETF是近年来加密货币市场的一个重要话题。与传统的ETF(交易型基金)类似,Solana ETF是一种投资基金,旨在跟踪Solana区块链生态系统的表现。许多投资者都在关注Solana ETF何时能获得批准,以及它的运作方式。本文将简要介绍Solana ETF的定义、其如何运作,并探讨…

    2025年12月9日
    000
  • 安币binance交易所 v3.1.7 官网最新安卓版

    安币binance交易所 v3.1.7 安卓版是为移动端用户设计的重要更新,致力于提供一个流畅、安全且功能全面的数字资产交易体验,使用户能够便捷地在移动设备上管理和交易其数字资产。 币安官网直达: 币安官方app: 核心交易功能 现货交易 v3.1.7版本提供了稳定而高效的现货交易功能。用户可以轻松…

    2025年12月9日
    000
  • 价值超37亿美元的ETH等待解锁,以太坊抛压风险几何?

    目录 多重因素驱动,以太坊质押解除规模创新高借贷利率飙升引发循环策略平仓LST/LRT 脱锚放大套利与清算风险机构资金迁移,质押生态格局生变价格上涨刺激获利了结大规模抛压短期难直接释放,市场仍有一定支撑空间 眼下,以太坊的多空分歧正愈发明显。随着 eth 价格冲击高位,质押撤回需求显著增加,市场对潜…

    2025年12月9日 好文分享
    000
  • 区块链技术说明:第一代、第二代、第三代区块链的发展历程及功能

    大家好! 这是区块链生态系统和加密货币世界的起点。然而,这项技术从未停止进化,持续催生出新的可能性、新型加密资产以及更丰富的交互方式。 本文将带你穿越区块链发展的三个时代。我们将探讨每一阶段为这个世界带来了哪些变革,并展望未来的方向。 第一代区块链 比特币 如前所述,第一代区块链的代表——比特币,诞…

    2025年12月9日
    000
  • 从 WLFI 代币看特朗谱家族的加密布局

    特朗谱家族通过WLFI代币将政治影响力金融化,构建加密民粹主义帝国,实则以去中心化之名行中心化之实,开启政治代币化新纪元。 特朗谱的名字再次搅动加密市场,但这次不是通过推文喊单,而是通过家族正式背书的WLFI代币。这枚看似普通的政治Meme币,实际上标志着特朗谱家族将加密领域纳入其权力延伸的战略布局…

    2025年12月9日
    000
  • 币安交易所转USDT到Gate.io交易所操作流程

    目录 Gate交易所注册地址及APP下载地址币安交易所注册地址及APP下载地址币安交易所转USDT到Gate.io交易所操作流程 如果你是刚刚开始接触数字货币交易的新手,不清楚如何在交易前完成资金划转,或者不知道怎样将自己持有的数字资产转给朋友,那么这篇文章将为你详细介绍如何在两个主流交易所之间进行…

    2025年12月9日 好文分享
    000
  • 如何接收您的第一个加密货币?步骤指南

    目录 开始之前步骤 1:添加帐户步骤 2:接收加密货币在 Ledger Live 上接收加密货币:示例 您刚刚设置好 ledger 设备,并开始探索加密货币。在 ledger live 上接收加密货币非常简单直接。只需简单几步,导航并协调您的设备和 ledger live 即可。  开始之前 下载并…

    2025年12月9日 好文分享
    000
  • 智能合约平台代币有哪些?

    以太坊ETH、币安BNB、SolanaSOL、波卡DOT等代币在支付、治理、质押中发挥核心作用,各平台在性能、去中心化、跨链互操作性方面各有优劣,新兴趋势如AI融合、账户抽象和SocialFi正拓展代币用例。 智能合约平台代币是访问和利用区块链网络功能的关键,它们通常用于支付交易费用、参与治理、质押…

    2025年12月9日
    000
  • 易欧交易所官方app v6.133.1 最新安卓版

    易欧交易所v6.133.1是安卓用户的一站式数字资产服务平台,提供币币交易、衍生品交易及质押、挖k池等金融增值服务,支持Web3账户实现多链资产管理,采用冷热账户分离与多重签名技术保障安全,界面友好并配备学院教程与跟单功能,满足从新手到专业用户的多元化需求。 易欧交易所官方应用 v6.133.1 版…

    2025年12月9日
    000
  • 币安将上线的Sapien(SAPIEN币)是什么?值得投资吗?SAPIEN代币经济与未来前景分析

    目录 什么是SapienSapien (SAPIEN) 最新动态什么是SAPIEN币代币分配代币效用Sapien未来路线图风险与挑战技术风险运营风险经济风险监管风险总结 现代人工智能系统依赖人类输入来达到准确性、可靠性和语境流畅性。 从构建数据集、验证模型输出,到提供算法无法推断的文化洞察力和领域专…

    2025年12月9日
    000

发表回复

登录后才能评论
关注微信