浅探 Windows 上获取磁盘信息的几种方式(一)

       获取磁盘信息是一个常见需求,如检查磁盘预留空间,开发磁盘碎片整理工具,系统性能优化等工具等。

        Windows 为此提供了各种接口,今天我们主要讲讲常用相关的三个API :

  • GetDiskFreeSpace
  • GetDiskFreeSpaceEx
  • GetDiskSpaceInformation

        如果你只是想获取磁盘空间总大小、剩余空间大小,那么很简单,直接调用 GetDiskFreeSpaceEx 即可,完。

        如果你还有进一步的获取磁盘信息的需求,请继续浏览下文。

        首先,让我们简单回顾下关于磁盘的基础知识。

扇区、簇、磁道和柱面

扇区(Sector)

  •    扇区是硬盘上最小的可寻址存储单位。
  •    硬盘读写操作的基本单位就是扇区。
  •    通常大小为512字节或更大(如4096字节)。这个值反映了磁盘的物理特性。
  •    扇区包含数据和错误检测与校正(ECC)信息,以确保数据的完整性。

簇(Cluster)

  •    簇是文件系统的最小分配单位。
  •    由一个或多个扇区组成,常见值:1、2、4、8、16、32、64 等扇区数。
  •    簇的大小通常在创建分区时设置,由文件系统和硬盘分区的大小决定。
  •    簇的大小会影响存储效率。

磁道(Track)

  •    磁道是硬盘上圆形的存储区域,是硬盘表面被划分的同心圆。每个磁道包含多个扇区。
  •    磁道是硬盘上物理存储数据的连续区域,磁头在读取或写入数据时会沿着磁道移动。
  •    由于磁道的外圈比内圈长,因此外圈的磁道可以存储更多的数据。

柱面(Cylinder)

  •   柱面是硬盘上所有具有相同编号的磁道组成的集合。在硬盘上,所有磁头可以同时读写相同编号的磁道,这些磁道就组成了一个柱面。
  •   柱面是硬盘上数据存储的逻辑单位,它允许磁头同时访问不同盘片上的相同位置。
  •   柱面的数量等于硬盘上磁头的数量乘以每面盘片的磁道数。

        以上是硬盘存储和数据组织的基础,了解它们有助于更好地理解硬盘的工作原理和数据存储方式,它们是硬盘数据存储和访问的基本结构。

        下面让我们通过以下三个不同的API分别获取磁盘的不同信息。

GetDiskFreeSpace

BOOL GetDiskFreeSpaceA(
  [in]  LPCSTR  lpRootPathName,           // 磁盘的根目录
  [out] LPDWORD lpSectorsPerCluster,      // 每簇扇区数
  [out] LPDWORD lpBytesPerSector,         // 每扇区字节数
  [out] LPDWORD lpNumberOfFreeClusters,   // 空闲簇数
  [out] LPDWORD lpTotalNumberOfClusters   // 总簇数
);

       函数名字似乎只是获取磁盘空闲空间的,但稍加仔细看参数便可知,该函数并未直接返回磁盘容量大小,而是返回簇、扇区的信息。  

        第一个参数为磁盘的根目录,注意,驱动器规范必须具有尾随反斜杠(例如,“C:\”)。

// 计算簇大小(字节)
DWORD clusterSize = lpSectorsPerCluster * lpBytesPerSector;

// 计算总空间(字节)
ULARGE_INTEGER totalBytes;
totalBytes.QuadPart = (ULONGLONG)lpTotalNumberOfClusters * 
                     lpSectorsPerCluster * 
                     lpBytesPerSector;

// 计算可用空间(字节)
ULARGE_INTEGER freeBytes;
freeBytes.QuadPart = (ULONGLONG)lpNumberOfFreeClusters * 
                     lpSectorsPerCluster * 
                     lpBytesPerSector;

       由此,我们可以写一个简单的磁盘分析小工具,运行效果如下:

  

GetDiskFreeSpaceEx

BOOL GetDiskFreeSpaceExW(
  [in, optional]  LPCWSTR         lpDirectoryName,
  [out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller,
  [out, optional] PULARGE_INTEGER lpTotalNumberOfBytes,
  [out, optional] PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

        这个函数简单明了,名副其实,就是获取磁盘空间大小信息的,注意参数是ULARGE_INTEGER 类型,获取剩余磁盘空间的示例代码如下:

        ULARGE_INTEGER freeBytesAvailable;
        ULARGE_INTEGER totalNumberOfBytes;
        ULARGE_INTEGER totalNumberOfFreeBytes;
        
        if (GetDiskFreeSpaceExA(path,
            &freeBytesAvailable,
            &totalNumberOfBytes,
            &totalNumberOfFreeBytes))
        {
            std::cout << "\nGetDiskFreeSpaceEx Results:\n";
            std::cout << "Logical Space Information:\n";
            std::cout << "- Total space: " << (totalNumberOfBytes.QuadPart / 
                      (1024.0 * 1024 * 1024)) << " GB\n";
            std::cout << "- Available space (with quota): " << 
                      (freeBytesAvailable.QuadPart / 
                      (1024.0 * 1024 * 1024)) << " GB\n";
            std::cout << "- Total free space (without quota): " << 
                      (totalNumberOfFreeBytes.QuadPart / 
                      (1024.0 * 1024 * 1024)) << " GB\n";
        }
        else {
            PrintError("GetDiskFreeSpaceEx");
        }

       

提示💡 

       另外还有个 SHGetDiskFreeSpace 函数,它是 SHGetDiskFreeSpaceEx的别名。内部实现是对 GetDiskFreeSpaceEx 函数的包装, 如果 GetDiskFreeSpaceEx 不可用,则通过调用 GetDiskFreeSpace 函数并操作返回值来模拟它。 

GetDiskSpaceInformation

HRESULT GetDiskSpaceInformationA(
  LPCSTR                 rootPath,
  DISK_SPACE_INFORMATION *diskSpaceInfo
);

         这个函数名字一看就不简单了,获取的信息会更丰富些。事实的确如此, 第二个参数 DISK_SPACE_INFORMATION 结构包含了丰富而详细的磁盘空间信息

typedef struct _DISK_SPACE_INFORMATION {
    ULONGLONG ActualTotalAllocationUnits;           // 实际总分配单元数
    ULONGLONG ActualAvailableAllocationUnits;       // 实际可用分配单元数
    ULONGLONG ActualPoolUnavailableAllocationUnits; // 池中不可用的分配单元数
    ULONGLONG CallerTotalAllocationUnits;           // 调用者可见的总分配单元数
    ULONGLONG CallerAvailableAllocationUnits;       // 调用者可见的可用分配单元数
    ULONGLONG CallerPoolUnavailableAllocationUnits; // 调用者可见的池中不可用分配单元数
    ULONGLONG UsedAllocationUnits;                  // 已使用的分配单元数
    ULONGLONG TotalReservedAllocationUnits;         // 总保留分配单元数
    ULONGLONG VolumeStorageReserveAllocationUnits;  // 卷存储保留分配单元数
    ULONGLONG AvailableCommittedAllocationUnits;    // 可用已提交分配单元数
    ULONGLONG PoolAvailableAllocationUnits;         // 池中可用分配单元数
    DWORD     SectorsPerAllocationUnit;             // 每个分配单元的扇区数
    DWORD     BytesPerSector;                       // 每扇区字节数
} DISK_SPACE_INFORMATION;
    DISK_SPACE_INFORMATION spaceInfo;
    
    if (SUCCEEDED(GetDiskSpaceInformation(path, &spaceInfo))) {
        std::wcout << L"Using GetDiskSpaceInformation:\n";
        std::wcout << L"Total bytes: " << spaceInfo.TotalNumberOfBytes << L"\n";
        std::wcout << L"Free bytes: " << spaceInfo.ActualFreeBytesAvailable << L"\n";
        std::wcout << L"Is quota supported: " << 
            (spaceInfo.QuotaInformation.QuotaSupported ? L"Yes" : L"No") << L"\n";
    }

        特别需要注意,该函数在 Windows 10 17763 或更高版本上才有效。

        另外,第一个参数和 GetDiskFreeSpace 一样,为磁盘的根目录,驱动器规范必须具有尾随反斜杠(例如,“C:\”)。

        

总结

     

        对于获取磁盘总大小、剩余空间这样简单的需求,GetDiskFreeSpaceEx 最为适合。如果只为Win10及之后的系统开发程序,且需要获取更为详尽的磁盘信息,则使用 GetDiskSpaceInformation。而GetDiskFreeSpace 更为通用,可以在Win 10 17763 之前的版本上正常工作。

        以上三个API的示例分别分为三个工程,代码打包在这里下载👇

        如果你对这方面信息感兴趣,我将在后续文章中进一步分享获取磁盘信息技术,欢迎评论留言交流。


参考 

GetDiskFreeSpaceA 函数 (fileapi.h) - Win32 apps | Microsoft Learn

GetDiskFreeSpaceExA 函数 (fileapi.h) - Win32 apps | Microsoft Learn

SHGetDiskFreeSpaceExW 函数 (shellapi.h) - Win32 apps | Microsoft Learn

getDiskFreeSpaceA 函数 (fileapi.h) - Win32 apps | Microsoft Learn

getDiskFreeSpaceExA 函数 (fileapi.h) - Win32 apps | Microsoft Learn

Hard Disk Drive Basics - NTFS.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/929409.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通信综合—8.通信网络安全

一、信息系统安全概述 1.信息系统的构成和分类 信息系统是将用于收集、处理、存储和传播信息的部件组织在一起而成的相关联的整体&#xff0c;般是由计算机硬件、网络和通信设备、计算机软件、信息资源和信息用户组成。它是以处理信息流为目的的人机一体化系统。信息系统主要…

语言的艺术:探秘基于GPT模型的文本生成与优化之美

语言的艺术&#xff1a;探秘基于GPT模型的文本生成与优化之美 在人工智能蓬勃发展的今天&#xff0c;语言模型如同文字艺术的魔术师&#xff0c;赋予了计算机以“书写”的能力。基于GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型的文本生成技术&#xf…

微服务篇-深入了解 XA 模式与 AT 模式、分布式事务(部署 TC 服务、微服务集成 Seata )

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 分布式事务 1.1 认识 Seata 2.0 部署 TC 服务 2.1 准备数据库表 2.2 准备配置文件 2.3 Docker 部署 3.0 微服务集成 Seata 3.1 引入依赖 3.2 改造配置 3.3 添加数…

王道考研编程题总结

我还在完善中&#xff0c;边复习边完善&#xff08;这个只是根据我自身总结的&#xff09; 一、 线性表 1. 结构体 #define MaxSize 40 typedef struct{ElemType data[MaxSize]&#xff1b;int length; }SqList 2. 编程题 1. 删除最小值 题意 &#xff1a;从顺序表中删除…

原生html+css+ajax实现二级下拉选择的增删改及树形结构列出

<?php $db_host localhost; $db_user info_chalide; $db_pass j8c2rRr2RnA; $db_name info_chalide; /* 数据库结构SQL CREATE TABLE categories ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, parent_id INT DEFAULT 0 ); */ try { $pdo new PD…

微信小程序介绍-以及写项目流程(重要)

前言&#xff1a;本篇文章介绍微信小程序以及项目介绍&#xff1a; 文章介绍&#xff1a;介绍了微信小程序常用的指令、组件、api。tips&#xff1a;最好按照官方文档来进行学习&#xff0c;大致可以我的目录来学习&#xff0c;对于写项目是没有问题的 微信小程序官方文档https…

Data Uncertainty Learning in Face Recognition 论文阅读

Data Uncertainty Learning in Face Recognition 论文阅读 Abstract1. Introduction2. Related Work3. Methodology3.1. Preliminaries3.2. Classification-based DUL for FR3.3. Regression-based DUL for FR3.4. Discussion of Related Works 4. Experiments4.1. Datasets an…

汽车产业数字化转型:协同创新破解挑战,平衡安全与流通

在数字经济时代的浪潮中&#xff0c;数据资源和数据信息已成为驱动各行各业转型升级的“新石油”。汽车产业&#xff0c;作为国民经济的重要支柱&#xff0c;正经历着前所未有的变革。随着数字化创新和转型的深入&#xff0c;数据在汽车全产业链中的作用和价值日益凸显。在这个…

vulnhub kioptirx1.2 超详细wp

探测 nmap --min-rate 10000 -p- 192.168.128.134 最小速率10000 nmap -sT -sV -sC -O 192.168.128.134 web打点 无弱口令 暴露cms寻找exp searchsploit LotusCMS -m 16982 [输入id号和参数m可以直接把东西复制到当前目录] 查看txt里面发现 都是xss没有rce github搜索到一个…

扫二维码进小程序的指定页面

草料二维码解码器 微信开发者工具 获取二维码解码的参数->是否登陆->跳转 options.q onLoad: function (options) {// console.log("options",options.q)if (options && options.q) {// 解码二维码携带的链接信息let qrUrl decodeURIComponent(optio…

mysql基础学习1

useradd -r -g mysql -s /bin/false mysql (-r)系统用户 不能登录 A temporary password is generated for rootlocalhost: d>#jT7rfoaz) 看是否启动 看进程 端口 直接连接 看日志 varchar (20) char(20)更耗空间 create table student_info(id int,name varchar(20),s…

Echarts使用平面方法绘制三维立体柱状图表

目录 一、准备工作 1.下载引入ECharts库 2.创建容器 二、绘制基本柱状 三、绘制立体柱状方法一 1.定义立方体形状 2.注册立方体形状 3.配置custom系列 4.设置数据 5.渲染图表 四、绘制立体柱状方法二 1.画前知识 2.计算坐标renderItem 函数 &#xff08;1&#x…

基于 MindQuantum 实现对 “天衍” 量子云平台真机的比特映射

MindQuantum 目前只支持量子模拟器&#xff0c;如果需要获得量子算法在真机上的实测数据&#xff0c;可以借助“天衍”量子云平台提供的真机。本文将介绍如何基于 MindQuantum 绘制“天衍”真机的拓扑图&#xff0c;并进而实现比特映射。 关于 MindQuantum 涉及比特映射的教程…

OpenBayes贝式计算创始人受邀参加第九届中国开源年会,分享 AI4S 前沿洞察

Open Source&#xff0c;Open Life&#xff0c;开源新生活&#xff01; 由开源社主办的第九届中国开源年会 (COSCon24) 于 2024 年 11 月 3 日在北京圆满落幕。本届大会为期 2 天&#xff0c;以 「开源新生活 - Open Source, Open Life 」 为主题&#xff0c;汇聚了来自全国各…

Day1 生信新手笔记

生信新手笔记 生信学习第一天笔记打卡。 转录组学中&#xff1a; 上游分析-基于linux&#xff0c;包括质控、过滤、比对、定量&#xff1b; 下游分析-基于R语言&#xff0c;包括差异分析、富集分析、可视化。 1. 级别标题 一个井号加空格 就是一级标题&#xff0c;两个井号加…

日拱一卒(9)——leetcode学习记录:两数组中位数

一、问题 给定两个大小分别为 m 和 n 的排序数组 nums1 和 nums2&#xff0c;要求你在 O(log(mn)) 的时间复杂度内找出这两个数组的中位数。 二、思路 时间复杂度O(log(n))代表随着操作数增加&#xff0c;剩余操作数递减&#xff0c;如二分法。 首先要建模&#xff0c;对这…

从 HTML 到 CSS:开启网页样式之旅(五)—— CSS盒子模型

从 HTML 到 CSS&#xff1a;开启网页样式之旅&#xff08;五&#xff09;—— CSS盒子模型 前言一、盒子模型的组成margin&#xff08;外边距&#xff09;&#xff1a;border&#xff08;边框&#xff09;&#xff1a;padding&#xff08;内边距&#xff09;&#xff1a;conten…

【区块链】深入理解区块链中的 Gas 机制

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 深入理解区块链中的 Gas 机制一、Gas 的基本概念1.1 为什么需要 Gas&#xff1f…

黑马JavaWeb-day06、07、08(SQL部分) _

文章目录 MYSQL概述数据模型SQL简介SQL分类 DDL数据库操作表操作 DML增&#xff08;INSERT&#xff09;改&#xff08;UPDATE&#xff09;删&#xff08;DELETE&#xff09; DQL基本查询条件查询&#xff08;where&#xff09;分组查询&#xff08;group by&#xff09;排序查询…

Kubernetes集群操作

查看集群信息&#xff1a; kubectl get nodes 删除节点 &#xff08;⽆效且显示的也可以删除&#xff09; 后期如果 要删除某个节点&#xff0c;为了不增加其他节点的访问压力&#xff0c;先增加一个节点&#xff0c;再删除要删除的节点 语法 &#xff1a;kubect delete…