2011-03-04 66 views
8

我需要在Win和* nix機器上獲取硬盤的規格。我在Linux上使用<hdreg.h>這樣的:如何在Linux中使用C++獲取硬件信息

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; 
    } 

我需要hd_driveid告訴我有關磁盤的更多信息。我想知道:

  • 分區數
  • 每個分區的規格(格式,標籤,標誌,尺寸,起點,軌道數量等)
  • 每缸曲目數
  • 總軌道數
  • 最大塊大小
  • 最小塊大小
  • 默認塊大小
  • 設備

我的問題的總大小爲:

  1. 是否有一個共同的 (獨立平臺)的方式來 連接硬件?我想使用 相同的代碼爲贏和* nix。 (即使 沒有辦法將 嵌入到cpp的彙編代碼中)
  2. 如果沒有,我如何在* nix中獲得上述信息?
+1

某些系統沒有分區......有些(通常在* BSD中)使用「分片」,而其他分區可能只是使用完整的硬盤。 (即未分區)。 – Arafangion 2011-03-04 13:36:59

回答

9

幾乎一切都在你的列表中有無關「硬盤的規格」:

  • 分區的數量取決於讀取分區表,如果您有任何擴展分區的分區表這些分區。設備驅動程序加載時,操作系統通常會爲您執行此操作。
  • 分區信息(即卷標)通常在分區表中不可用。您需要猜測文件系統類型並解析文件系統頭。分區表中唯一的東西是「類型」字節,它並沒有告訴你所有的東西,以及開始/大小。
  • 硬盤不會給你「真正的」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.

計算尺寸更大的獲得字節大小

如果你告訴我們你爲什麼想要這個信息,這可能有助於...

+1

謝謝tc。我用'T = t×S'來克服,其中S是'扇區',t是軌道數。我不知道'塊大小'是什麼,除了我的老師C#示例以外,我找不到它。在這個例子中有一個'ManagementObject'的實例,這些信息是通過一個字符串索引器提取出來的......(我忘了說我在寫作業:-) – 2011-03-04 13:48:40

+1

像hd.model,hd.serial_no這樣的參數是真實。可能有人給我一個提示,爲什麼我得到一個hd_driveid.sector_bytes等於零?我只需要這個參數,它等於零... – Tebe 2012-04-11 22:48:12

+1

@shbk:開始一個新的問題可能會更好,它說明你正在使用的硬件,你運行的完整代碼以及它輸出的內容。如果你解釋你試圖最終實現什麼,它也更容易幫助。 – 2012-04-16 15:37:46

3

不,沒有平臺無關的方式。甚至沒有* nix的方式。只有Linux的方式。

在Linux中,所有相關信息都可在/proc文件系統的各種文件中找到。 /proc/devices會告訴你哪些設備存在(即使設備不可用,/dev/中的文件也可能存在,但在這種情況下打開它們將會失敗),/proc/partitions會告訴你每個磁盤上有哪些分區可用,必須查看各種子目錄中的信息。只要看看你需要的某個linux系統。

+1

感謝您的回答,但我找不到我需要的答案......我想知道如何創建'/ proc'中的文件?我想在我的程序中自己獲得硬件信息:-)(與它們在'/ proc'中生成的方式相同) – 2011-03-04 12:38:22

+3

@將proc中的'文件'刷新是真正的特殊文件系統(稱爲procfs),它讀取和/或直接寫入內核。您將需要深入Linux內核以找出procfs如何獲取其數據。 procfs的重點在於公開無需成爲內核黑客的數據。 – KitsuneYMG 2011-03-04 12:54:19

+1

@Sorush:你將不得不挖掘一下,收集你所需要的一切。不幸的是,我現在不在Linux系統上,我不記得確切的文件,但有'/ proc/bus/ide'和'/ proc/bus/scsi'之類的東西,還有一些文件您需要收集的各種信息。 – 2011-03-07 13:54:32

1
//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); 
//--- 
2
//------------------------------------------------- 
// 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; 
//---