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:
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:
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:
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:
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.