当前位置: 首页 > news >正文

C++编程实践—C++处理磁盘大小

一、磁盘容量监控

在实际的编程,经常会遇到对磁盘容量进行监控的情况。当磁盘的应用达到一个阀值时,就需要向用户发出报警信息,并针对具体的操作进行限制,以防止出现意外的事故。一般来说,对硬盘的处理,都是各个平台提供自己专属的API来保证对硬盘容量获取的准确性。但随着C++标准的演进,在C++17中也提供了相关的方法。
在前面的“Linux下获得磁盘和目录大小”中已经给出了一个完整的例子。本文将通过C++17标准中的方法与之对比,可以更好的理解相关的应用。

二、Linux下传统的方式

在Linux中,对硬盘的监控的方法有几种方法:

  1. 使用命令方式
    可以通过命令行或在C++中使用相关接口如system来实现命令的调用:
    iRet=popen(cmd.c_str()"r");fgets(buffer.data(),buffer.size(),pipe.get()
    buffer.data()中就是相关的内容
  2. 使用statvfs接口
    此函数是POSIX推荐的接口,头文件为 <sys/statvfs.h>,相对上层,应用方式如下:
    intret=statvfs(devInfo.mountPoint.c_str(),&fsStat);
  3. 使用statfs
    它需要包含#include <sys/vfs.h> 或 #include <sys/statfs.h>,是一个更底层的函数。应用如下:
    ret=statfs(path.c_str(),&s);

三、Windows下传统的方式

在Windows平台上,std::filesystem::space接口是使用GetDiskFreeSpaceExW接口来实现的。其定义如下:

BOOLGetDiskFreeSpaceEx(LPCWSTR lpRootPathName,// 根路径PULARGE_INTEGER lpFreeBytesAvailable,// 用户可用空间 : space_info.availablePULARGE_INTEGER lpTotalNumberOfBytes,// 总空间 :space_info.capacityPULARGE_INTEGER lpTotalNumberOfFreeBytes// 总空闲空间 : space_info.free);

四、c++17中的方法

在C++17后,标准库提供了库,其中的std::filesystem::space可以用来获取相关的磁盘的信息。其基本的定义如下:

structspace_info{std::uintmax_tcapacity;//文件系统的总大小,单位为字节std::uintmax_tfree;//可用空间,单位为字节std::uintmax_tavailable;//非特权进程可用的空闲空间,可能小于free};

在Linux上其具体的实现,其实就是调用statvfs接口。使用它需要注意以下几点:

  1. 权限,在Linux上很多情况下需要权限,否则可能无法成功读取相关的文件系统信息。此时要注意看返回的错误代码
  2. 不同分区处理,可能需要遍历所有的挂载点。这需要去读取/proc/mounts或/etc/mtab,然后再次调用相关接口即可
  3. 需要注意平台是32位还是64位。32位情况下可能对大磁盘(大于2T)的信息描述不对。因为使用字节描述,可能会溢出

五、例程

下面看传统的实现以及C++17的实现例程,Windows平台:

#include<windows.h>#include<iostream>#include<string>boolGetDiskSpaceInfo(conststd::wstring&path,unsignedlonglong&totalBytes,unsignedlonglong&freeBytes,unsignedlonglong&availableBytes){ULARGE_INTEGER totalAvailable;ULARGE_INTEGER totalBytes;ULARGE_INTEGER totalFreeBytes;BOOL ret=GetDiskFreeSpaceExW(path.c_str(),&totalAvailable,&totalBytes,&totalFreeBytes);if(!ret){returnfalse;}availableBytes=totalAvailable.QuadPart;totalBytes=totalBytes.QuadPart;freeBytes=totalFreeBytes.QuadPart;returntrue;}//GBstd::stringFormatBytes(unsignedlonglongbytes){constdoublegb=bytes/(1024.0*1024.0*1024.0);charbuf[64];snprintf(buf,sizeof(buf),"%.2f GB",gb);returnstd::string(buf);}intmain(){std::wstring path=L"C:\\";unsignedlonglongtotal,freeSpace,available;GetDiskSpaceInfo(path,total,freeSpace,available);return0;}

Linux中传统的应用可参看“Linux下获得磁盘和目录大小”的例程。下面看C++17实现(来自cppreference):

#include<cstdint>#include<filesystem>#include<iostream>#include<locale>std::uintmax_tdisk_usage_percent(conststd::filesystem::space_info&si,bool is_privileged=false)noexcept{if(constexpr std::uintmax_tX(-1);si.capacity==0||si.free==0||si.available==0||si.capacity==X||si.free==X||si.available==X)return100;std::uintmax_tunused_space=si.free,capacity=si.capacity;if(!is_privileged){conststd::uintmax_tprivileged_only_space=si.free-si.available;unused_space-=privileged_only_space;capacity-=privileged_only_space;}conststd::uintmax_tused_space{capacity-unused_space};return100*used_space/capacity;}voidprint_disk_space_info(autoconst&dirs,intwidth=14){(std::cout<<std::left).imbue(std::locale("en_US.UTF-8"));for(constautos:{"Capacity","Free","Available","Use%","Dir"})std::cout<<"│ "<<std::setw(width)<<s<<' ';for(std::cout<<'\n';autoconst&dir:dirs){std::error_code ec;conststd::filesystem::space_info si=std::filesystem::space(dir,ec);for(autox:{si.capacity,si.free,si.available,disk_usage_percent(si)})std::cout<<"│ "<<std::setw(width)<<static_cast<std::intmax_t>(x)<<' ';std::cout<<"│ "<<dir<<'\n';}}intmain(){constautodirs={"/dev/null","/tmp","/home","/proc","/null"};print_disk_space_info(dirs);}

上面的代码还是比较简单的,不过要想弄清楚,建议还是上机真正调试一下。

六、总结

通过上面的分析可以发现,抽象的层次就是不断的为终端用户减负而把具体的复杂实现隐藏在接口内部。这也给开发者提供了具象化的实践例子。这也符合软件设计中的抽象层解决一切的情况。

http://www.jsqmd.com/news/485334/

相关文章:

  • 微信小程序 舞蹈课程预约系统 舞房约课系统
  • 2026年专科生必看!千笔·降AI率助手,最受欢迎的降AI率网站
  • 生成引擎优化(GEO)提升数字内容创作效率与用户体验的实践指南
  • 2026深度测评10款论文降重工具:3个免费方法亲测有效!谁是降重的最优解?(附论文降重避坑指南)
  • LangChain 实战:大模型对话记忆模块(附完整代码 + Web 案例)
  • 【黎阳之光:以无线专网与视频孪生,赋能智慧广电与数字中国】
  • Hello Vibe:面向小白/入门级开发者的AI编程指南
  • 虚拟机创建
  • 大厂量产的两相交错TCM图腾柱变频控制PFC+全桥LLC源代码 PFC可通过变频控制实现软开关
  • 建议收藏|一键生成论文工具,千笔写作工具 VS Checkjie,多场景适配首选
  • 5G 核心网用户面功能实体 UPF:技术演进与选型指南
  • 百度贴吧一键自动签到脚本(附Python脚本 下载方式)教程 养账号用
  • 所有人都在夸 AI 伴侣,我却看到 3 个正在发生的“情感退化”信号?
  • 鸿蒙应用开发UI基础第二十五节:手把手教打造第三方库HAR构建、混淆与发布 - 鸿蒙
  • NDW系列微机控制材料扭转试验机
  • 破局增长|中小企业低成本高回报的6个实用路径-佛山鼎策创局破局增长咨询
  • python搭建webrtc音视频服务端客户端
  • 第一个小项目天气预报
  • 风光储并网控制系统的设计与Matlab Simulink仿真建模研究
  • 501.二叉搜索树中的众数()
  • Agent Infra 到底解决了什么,没解决什么?
  • 【LLM进阶-Agent】8. Reflexion Agent 介绍
  • 聊聊全国起重机保养服务源头厂家哪家好,性价比高吗? - 工业推荐榜
  • 高性价比的逆变器维修工厂价格多少,杭州能用的有哪些 - myqiye
  • 2026年重庆全案装修公司推荐,专业全案装修服务哪家好 - 工业品牌热点
  • 效率直接起飞! 更贴合继续教育的降AI率网站,千笔·专业降AIGC智能体 VS 学术猹
  • 深聊双梁行车行吊,杭起起重等品牌值得关注 - 工业设备
  • 原创排序算法 SplitMergeSort:一种非二分、非传统分治的全新排序思路
  • 显存暴降92%!哈工大为线性注意力开辟了新道路
  • 浮点STM32F4电机控制:磁链观测器与VESC中的0速闭环启动实现方法