C++编程实践—C++处理磁盘大小
一、磁盘容量监控在实际的编程经常会遇到对磁盘容量进行监控的情况。当磁盘的应用达到一个阀值时就需要向用户发出报警信息并针对具体的操作进行限制以防止出现意外的事故。一般来说对硬盘的处理都是各个平台提供自己专属的API来保证对硬盘容量获取的准确性。但随着C标准的演进在C17中也提供了相关的方法。在前面的“Linux下获得磁盘和目录大小”中已经给出了一个完整的例子。本文将通过C17标准中的方法与之对比可以更好的理解相关的应用。二、Linux下传统的方式在Linux中对硬盘的监控的方法有几种方法使用命令方式可以通过命令行或在C中使用相关接口如system来实现命令的调用iRetpopen(cmd.c_str()r);fgets(buffer.data(),buffer.size(),pipe.get()buffer.data()中就是相关的内容使用statvfs接口此函数是POSIX推荐的接口头文件为 sys/statvfs.h相对上层应用方式如下intretstatvfs(devInfo.mountPoint.c_str(),fsStat);使用statfs它需要包含#include sys/vfs.h 或 #include sys/statfs.h是一个更底层的函数。应用如下retstatfs(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);四、c17中的方法在C17后标准库提供了库其中的std::filesystem::space可以用来获取相关的磁盘的信息。其基本的定义如下structspace_info{std::uintmax_tcapacity;//文件系统的总大小单位为字节std::uintmax_tfree;//可用空间单位为字节std::uintmax_tavailable;//非特权进程可用的空闲空间可能小于free};在Linux上其具体的实现其实就是调用statvfs接口。使用它需要注意以下几点权限在Linux上很多情况下需要权限否则可能无法成功读取相关的文件系统信息。此时要注意看返回的错误代码不同分区处理可能需要遍历所有的挂载点。这需要去读取/proc/mounts或/etc/mtab然后再次调用相关接口即可需要注意平台是32位还是64位。32位情况下可能对大磁盘大于2T的信息描述不对。因为使用字节描述可能会溢出五、例程下面看传统的实现以及C17的实现例程Windows平台#includewindows.h#includeiostream#includestringboolGetDiskSpaceInfo(conststd::wstringpath,unsignedlonglongtotalBytes,unsignedlonglongfreeBytes,unsignedlonglongavailableBytes){ULARGE_INTEGER totalAvailable;ULARGE_INTEGER totalBytes;ULARGE_INTEGER totalFreeBytes;BOOL retGetDiskFreeSpaceExW(path.c_str(),totalAvailable,totalBytes,totalFreeBytes);if(!ret){returnfalse;}availableBytestotalAvailable.QuadPart;totalBytestotalBytes.QuadPart;freeBytestotalFreeBytes.QuadPart;returntrue;}//GBstd::stringFormatBytes(unsignedlonglongbytes){constdoublegbbytes/(1024.0*1024.0*1024.0);charbuf[64];snprintf(buf,sizeof(buf),%.2f GB,gb);returnstd::string(buf);}intmain(){std::wstring pathLC:\\;unsignedlonglongtotal,freeSpace,available;GetDiskSpaceInfo(path,total,freeSpace,available);return0;}Linux中传统的应用可参看“Linux下获得磁盘和目录大小”的例程。下面看C17实现来自cppreference#includecstdint#includefilesystem#includeiostream#includelocalestd::uintmax_tdisk_usage_percent(conststd::filesystem::space_infosi,bool is_privilegedfalse)noexcept{if(constexpr std::uintmax_tX(-1);si.capacity0||si.free0||si.available0||si.capacityX||si.freeX||si.availableX)return100;std::uintmax_tunused_spacesi.free,capacitysi.capacity;if(!is_privileged){conststd::uintmax_tprivileged_only_spacesi.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(autoconstdirs,intwidth14){(std::coutstd::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;autoconstdir:dirs){std::error_code ec;conststd::filesystem::space_info sistd::filesystem::space(dir,ec);for(autox:{si.capacity,si.free,si.available,disk_usage_percent(si)})std::cout│ std::setw(width)static_caststd::intmax_t(x) ;std::cout│ dir\n;}}intmain(){constautodirs{/dev/null,/tmp,/home,/proc,/null};print_disk_space_info(dirs);}上面的代码还是比较简单的不过要想弄清楚建议还是上机真正调试一下。六、总结通过上面的分析可以发现抽象的层次就是不断的为终端用户减负而把具体的复杂实现隐藏在接口内部。这也给开发者提供了具象化的实践例子。这也符合软件设计中的抽象层解决一切的情况。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2416135.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!