本文对linux下块设备文件全部适用。

通过lseek

linux下并没有专门用于获取硬盘设备大小的系统调用。因为完全不需要。linux下可以通过打开设备文件(块设备),执行lseek(fd,0,2)跳转到文件结尾处,通过lseek返回值获取设备文件大小。
linux内核启动时会获取硬盘的总大小,保存在内核中,对其读取或写入时都要对总大小做判断,读取位置是否已经超出最大值。而执行lseek(fd,0,2)会将当前文件偏移值直接设置为文件总大小,并返回最大值。
以下为执行代码

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc,char *argv[])
{
    int fd;

    if(argc!=2)
    {
        printf("argv !=2 \n");
        return;
    }

    fd=open(argv[1],O_RDONLY);

    if(fd==-1)
    {
        printf("open file wrong \n");
        return;
    }

    off_t off=lseek(fd,0,SEEK_END);
    //多少个G
    long long gs=off/1024/1024/1024;

    printf("size of  %d   %lld   %lld\n",sizeof(off_t),off,gs);

    return;
}

不过编译的时候要注意,32位的系统下,gcc命令要执行gcc -D_FILE_OFFSET_BITS=64,不然获取的偏移最大只能是4G。

执行时以硬盘设备名作为命令行参。

./a.out /dev/sda

通过ioctl

每个设备文件都可以执行ioctl以获取对应设备的信息。

int ioctl(int handle, int cmd,...);
返回值:成功为0,出错为-1

块设备的话可以执行它获取块设备大小

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <stdint.h>
#include <unistd.h>

int main(void)
{
    int fd;
    uint64_t size;
    int len;
    int r;

    if ((fd = open("/dev/sda", O_RDONLY)) < 0)
    {
        printf("open error %d\n", errno);
        exit(-1);
    }

    if ((r = ioctl(fd, BLKGETSIZE64, &size)) < 0)
    {
        printf("ioctl error %d\n", errno);
        exit(-1);
    }

    len = (size>>30);
    printf("size of sda = %d G\n", len);

    return 0;
}

通过ioctl–2

以下代码来自fdsik命令源码
//获取设备每个扇区的大小
int blkdev_get_sector_size(int fd, int *sector_size)
{
#ifdef BLKSSZGET
    if (ioctl(fd, BLKSSZGET, sector_size) >= 0)
        return 0;
    return -1;
#else
    *sector_size = DEFAULT_SECTOR_SIZE;
    return 0;
#endif
}

//获取磁头,磁道,扇区数
int blkdev_get_geometry(int fd, unsigned int *h, unsigned int *s)
{
#ifdef HDIO_GETGEO
    struct hd_geometry geometry;

    if (ioctl(fd, HDIO_GETGEO, &geometry) == 0) {
        *h = geometry.heads;
        *s = geometry.sectors;
        return 0;
    }
#else
    *h = 0;
    *s = 0;
#endif
    return -1;
}

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐