Embedded Linux QT Development: How to Get Disk Space Size

Click on the “Embedded Application Research Institute“, select “Top/Star Public Account

Valuable Content Delivered First!

Source | Embedded Application Research Institute

Organization & Formatting | Embedded Application Research Institute

On Windows systems, when we open My Computer, we can see the available space and total space of each disk, as shown below:

Embedded Linux QT Development: How to Get Disk Space Size

In the development of products combining embedded Linux and QT interfaces, we often need to implement such a feature in the file management module. So how do we achieve this?

Method 1: (Refer to QT Expert – Feiyang Qingyun’s implementation of disk capacity space control)

Utilize the df command provided by the Linux system to obtain information. For example, we can add the -h parameter to get the output in a human-readable format, as shown below:

Embedded Linux QT Development: How to Get Disk Space Size

Based on the file system of the Weidongshan imx6ull development board

After executing df -h, we can find a certain pattern, that is, the output is given line by line, and each line is separated by spaces. Therefore, we can use QT’s string splitting method and some simple logic to extract the content of one line.

QT expert – Feiyang Qingyun introduced this method in his disk capacity control, open-source repository:

https://gitee.com/feiyangqingyun/QWidgetDemo?_from=gitee_search

The function to parse a line is as follows:

#include "mainwindow.h"
#include "ui_mainwindow.h"

void MainWindow::Get_Disk(const QString &result, const QString &name)
{
    uint8_t index = 0;
    uint8_t percent = 0;
    QString dev, use, free, all;
    QStringList list = result.split(" ");
    for (int i = 0; i < list.count(); i++)
    {
        QString s = list.at(i).trimmed();
        if (s == "")
            continue;
        index++;
        if (index == 1)
            dev = s;
        else if (index == 2)
            all = s;
        else if (index == 3)
            use = s;
        else if (index == 4)
            free = s;
        else if (index == 5) {
            percent = s.left(s.length() - 1).toInt();
            break;
        }
    }
    if (name.length() > 0)
        dev = name;
    qDebug() << "Device Name:" << dev ;
    qDebug() << "Total Space:" << all ;
    qDebug() << "Used Space:" << use ;
    qDebug() << "Free Space:" << free ;
    qDebug() << "Used Space Percentage:" << percent << "%";
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QString str = "/dev/sda4                14.4G      7.4G      7.0G  52% /mnt";
    Get_Disk(str,"/dev/sda4");
}

MainWindow::~MainWindow()
{
    delete ui;
}

Running results:

Embedded Linux QT Development: How to Get Disk Space Size

This method does not require understanding the implementation principle; simply put, it is a string parsing process. Combine QT’s QProcess function or the Linux C provided popen function to call the df -h command to obtain disk capacity information, and then use this method to read each line in a loop, combining it with your product’s business logic to obtain the corresponding content.

Method 2: Directly move the df command code over and combine it with QT

Based on the statfs function implementation, this method is actually the implementation principle of the df command, which can be used to query file system related information. The implementation of the df command is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/statfs.h>
 
static int ok = EXIT_SUCCESS;
// Calculate based on the size of the mounted file
static void printsize(long double n)
{
    char unit = 'K';
    n /= 1024;
    if (n > 1024) {
        n /= 1024;
        unit = 'M';
    }
    if (n > 1024) {
        n /= 1024;
        unit = 'G';
    }
    printf("%-4.1Lf%c", n, unit);
}
 
static void df(char *s, int always) {
    struct statfs st;
    // The statfs function can be used to query file system related information.
    if (statfs(s, &st) < 0) {
        fprintf(stderr, "%s: %s\n", s, strerror(errno));
        ok = EXIT_FAILURE;
    } else {
        if (st.f_blocks == 0 && !always)
            return;        
        printf("%-20s  ", s);
        printsize((long double)st.f_blocks * (long double)st.f_bsize);
        printf("  ");
        printsize((long double)(st.f_blocks - (long double)st.f_bfree) * st.f_bsize);
        printf("  ");
        printsize((long double)st.f_bfree * (long double)st.f_bsize);
        printf("   %d\n", (int) st.f_bsize);
    }
}
 
int df_main(int argc, char *argv[]) {
    printf("Filesystem             Size   Used   Free   Blksize\n");
    if (argc == 1) {
        char s[2000];
        // Mounted files are displayed under /proc/mounts
        FILE *f = fopen("/proc/mounts", "r");
 
        while (fgets(s, 2000, f)) {
            char *c, *e = s;
 
            for (c = s; *c; c++) {
                if (*c == ' ') {
                    e = c + 1;
                    break;
                }
            }
 
            for (c = e; *c; c++) {
                if (*c == ' ') {
                    *c = '\0';
                    break;
                }
            }
 
            df(e, 0);
        }
 
        fclose(f);
    } else {
        int i;
 
        for (i = 1; i < argc; i++) {
            df(argv[i], 1);
        }
    }
 
    exit(ok);
}

As a veteran of Ctrl-C and Ctrl-V in the workplace for many years, integrating this into my own code logic is quite easy. After a simple modification, the requirements are met:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <sys/vfs.h>
#include <sys/stat.h>
#include <dirent.h>

/* Check if the directory exists */
bool dirIsExist(const char *file_path)
{
    DIR * mydir = NULL;
    if ((mydir = opendir(file_path)) == NULL)
        return false;
    closedir(mydir);
    return true;
}

/* Get the available space and total space of the disk */
int getDiskInfo(const char *path,double * available,double *total)
{
    uint64_t blocksize;
    uint64_t totalsize;
    uint64_t availablesize;
    struct statfs diskInfo;
    if(dirIsExist(path))
        statfs(path, &diskInfo);
    else
        return -1 ;
    // Number of bytes in each block
    blocksize = diskInfo.f_bsize;
    // Total bytes, f_blocks is the number of blocks
    totalsize = blocksize * diskInfo.f_blocks;
    // Size of available space
    availablesize = diskInfo.f_bavail * blocksize;
    *available = availablesize ;
    *total = totalsize ;
    return 0 ;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    char av_unit = 'K';
    char total_unit = 'K';
    double availablesize = 0.00 ;
    double totalsize = 0.00 ;
    getDiskInfo("/mnt",&availablesize,&totalsize); 
    availablesize /= 1024 ;
    if(availablesize > 1024){
        availablesize /= 1024 ;
        av_unit = 'M';
    }
    if(availablesize > 1024){
        availablesize /= 1024 ;
        av_unit = 'G';
    }
    totalsize /= 1024 ;
    if(totalsize > 1024){
        totalsize /= 1024 ;
        total_unit = 'M';
    }
    if(totalsize > 1024){
        totalsize /= 1024 ;
        total_unit = 'G';
    }
    qDebug() <<"availablesize:" <<  QString("%1%2").arg(QString::number(availablesize, 'f', 1)).arg(av_unit) ;
    qDebug() <<"totalsize:" << QString("%1%2").arg(QString::number(totalsize, 'f', 1)).arg(total_unit) ;
}

After cross-compiling under Linux and running this program on the development board, the output is as follows:

Embedded Linux QT Development: How to Get Disk Space Size

The methods of the experts are straightforward, but I personally recommend using Method 2 to implement the logic, as it offers more operational flexibility. In the next issue, we will combine iwlist and wpa_cli to implement WIFI scanning, connecting, and status querying.

Previous Highlights

Embedded Linux QT Application Development WIFI Search, Display, and Connection Ideas

Embedded Linux Detection of USB Drive Insertion and Removal Combined with QT Interface Development Ideas

Embedded QT Application Development for QR Code Generation

How to Solve Incomplete Data Reception in Qt Serial Communication?

QMap in QT Can Also Achieve Table-Driven

If you find this article helpful, please click<span>[Looking]</span> and share it, which is also a support for me.

Leave a Comment