如何使用 C++ 在 Linux 中获取硬件信息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5193625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Howto get hardware information in Linux using C++
提问by sorush-r
I need to get specifications of hard disk on both Win and *nix machines. I used <hdreg.h>
on Linux like this:
我需要在 Win 和 *nix 机器上获得硬盘的规格。我<hdreg.h>
在 Linux 上是这样使用的:
static struct hd_driveid hd;
int device;
if ((device = open("/dev/sda", O_RDONLY | O_NONBLOCK)) < 0)
{
cerr << "ERROR: Cannot open device /dev/sda \n";
exit(1);
}
if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
{
cout << hd.model << endl;
cout << hd.serial_no << endl;
cout << hd.heads << endl;
}
I need hd_driveid
to tell me some more information about disk. I want to know:
我需要hd_driveid
告诉我一些有关磁盘的更多信息。我想知道:
- Number of partitions
- Specifications of each partition (format, label, flags, size, start point, number of tracks etc.)
- Number of tracks per cylinder
- Number of total tracks
- Maximum block size
- Minimum Block size
- Default block size
- Total size of device
- 分区数
- 每个分区的规格(格式、标签、标志、大小、起点、轨道数等)
- 每个圆柱体的轨道数
- 总曲目数
- 最大块大小
- 最小块大小
- 默认块大小
- 设备总尺寸
My questions are:
我的问题是:
- Is there a common (platform-independent) way to connect hardware? I would like use same code for win and *nix. (even if there was no way other than embedding assembly code into cpp)
- If there isn't, how do I get above information in *nix?
- 是否有一种通用的(独立于平台的)方式来连接硬件?我想对 win 和 *nix 使用相同的代码。(即使除了将汇编代码嵌入 cpp 之外别无他法)
- 如果没有,我如何在 *nix 中获取上述信息?
采纳答案by tc.
Nearly everything in your list has nothing to do with "specifications of hard disk":
您列表中的几乎所有内容都与“硬盘规格”无关:
- The number of partitions depends on reading the partition table, and if you have any extended partitions, the partition tables of those partitions. The OS will usually do this bit for you when the device driver loads.
- Partition information (namely the volume label) typically isn't available in the partition table. You need to guess the file system type and parse the file system header. The only thing in the partition table is the "type" byte, which doesn't tell you all that much, and the start/size.
- Hard drives won't give you "real" CHS information. Additionally, the CHS information that the drive provides is "wrong" from the point of view of the BIOS (the BIOS does its own fudging).
- Hard drives have a fixed sector size, which you can get with
hd_driveid.sector_bytes
(usually 512, but some modern drives use 4096). I'm not aware of a maximum "block size", which is a property of the filesystem. I'm also not sure why this is useful. The total size in sectors is in
hd_driveid.lba_capacity_2
. Additionally, the size in bytes can probably be obtained with something like#define _FILE_OFFSET_BITS 64 #include <sys/types.h> #include <unistd.h> ... off_t size_in_bytes = lseek(device, 0, SEEK_END); if (size_in_bytes == (off_t)-1) { ... error, error code in ERRNO ... }
Note that in both cases, it'll probably be a few megabytes bigger than sizes calculated by C×H×S.
- 分区的数量取决于读取分区表,如果您有任何扩展分区,则这些分区的分区表。当设备驱动程序加载时,操作系统通常会为你做这件事。
- 分区信息(即卷标)通常在分区表中不可用。您需要猜测文件系统类型并解析文件系统头。分区表中唯一的东西是“类型”字节,它不会告诉你那么多,以及开始/大小。
- 硬盘驱动器不会为您提供“真实”的 CHS 信息。此外,从 BIOS 的角度来看,驱动器提供的 CHS 信息是“错误的”(BIOS 会自行伪造)。
- 硬盘驱动器具有固定的扇区大小,您可以使用它
hd_driveid.sector_bytes
(通常为 512,但一些现代驱动器使用 4096)。我不知道最大“块大小”,这是文件系统的一个属性。我也不确定为什么这很有用。 扇区的总大小为
hd_driveid.lba_capacity_2
。此外,可能可以通过类似的方式获得以字节为单位的大小#define _FILE_OFFSET_BITS 64 #include <sys/types.h> #include <unistd.h> ... off_t size_in_bytes = lseek(device, 0, SEEK_END); if (size_in_bytes == (off_t)-1) { ... error, error code in ERRNO ... }
请注意,在这两种情况下,它可能会比 C×H×S 计算的大小大几兆字节。
It might help if you told us why you wanted this information...
如果您告诉我们您为什么需要此信息,这可能会有所帮助...
回答by Jan Hudec
No, there is no platform-independent way. There is even no *nix way. There is just Linux way.
不,没有独立于平台的方式。甚至没有 *nix 方法。只有Linux的方式。
In Linux, all relevant information is available in various files in the /proc
filesystem. The /proc/devices
will tell you what devices there are (the files in /dev/
may exist even when the devices are not available, though opening them will fail in that case), /proc/partitions
will tell you what partitions are available on each disk and than you'll have to look in the various subdirectories for the information. Just look around on some linux system where is what you need.
在 Linux 中,所有相关信息都可以在文件/proc
系统的各种文件中找到。该/proc/devices
会告诉你有哪些设备(在文件中/dev/
可能存在,即使设备不可用,但打开它们会在这种情况下失败),/proc/partitions
会告诉你什么分区都可以在每个磁盘上,比你必须看看在各个子目录中的信息。只需在某些 linux 系统上看看您需要什么。
回答by fpmurphy
For GNU/Linux have a look at this: obtaining hard disk metadata
对于 GNU/Linux 看看这个:获取硬盘元数据
回答by Amit Vujic
//Piece of code working for me with Boost LIB usage
//-----------------------------------------------------
#include <sys/sysinfo.h>
#include <boost/filesystem.hpp>
//---
using namespace boost::filesystem;
//---
struct sysinfo info;
sysinfo( &info );
//---
space_info si = space(".");
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
//---
std::string cpunumber = to_string(num_cpu);
std::string cpufrequency = cpu_freq.str();
std::string cputemp = cpu_temp.str();
std::string mem_size = to_string( (size_t)info.totalram * (size_t)info.mem_unit );
std::string disk_available = to_string(si.available);
std::string fslevel = to_string( (si.available/si.capacity)*100 );
//---
回答by Amit Vujic
//-------------------------------------------------
// Without Boost LIB usage
//-------------------------------------------------
#include <sys/statvfs.h>
#include <sys/sysinfo.h>
//-------------------------------------------------
stringstream strStream;
unsigned long hdd_size;
unsigned long hdd_free;
ostringstream strConvert;
//---
struct sysinfo info;
sysinfo( &info );
//---
struct statvfs fsinfo;
statvfs("/", &fsinfo);
//---
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
strStream << cpu_freq.rdbuf();
std::string cpufrequency = strStream.str();
//---
strStream.str("");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
strStream << cpu_temp.rdbuf();
strConvert<< fixed << setprecision(2) << std::stof(strStream.str());
std::string cputemp = strConvert.str();
//---
std::string mem_size = to_string( (size_t)info.totalram * (size_t)info.mem_unit );
//---
hdd_size = fsinfo.f_frsize * fsinfo.f_blocks;
hdd_free = fsinfo.f_bsize * fsinfo.f_bfree;
//---
std::cout << "CPU core number ==" << num_cpu << endl;
std::cout << "CPU core speed ==" << cpufrequency << endl;
std::cout << "CPU temperature (C) ==" << cputemp << endl;
//---
std::cout << "Memory size ==" << mem_size << endl;
//---
std::cout << "Disk, filesystem size ==" << hdd_size << endl;
std::cout << "Disk free space ==" << hdd_free << endl;
//---