How to determine how much free space on a drive in

2019-01-14 22:46发布

问题:

I'm using Qt and want a platform-independent way of getting the available free disk space.

I know in Linux I can use statfs and in Windows I can use GetDiskFreeSpaceEx(). I know boost has a way, boost::filesystem::space(Path const & p).

But I don't want those. I'm in Qt and would like to do it in a Qt-friendly way.

I looked at QDir, QFile, QFileInfo -- nothing!

回答1:

I know It's quite old topic but somebody can still find it useful.

Since QT 5.4 the QSystemStorageInfo is discontinued, instead there is a new class QStorageInfo that makes the whole task really simple and it's cross-platform.

QStorageInfo storage = QStorageInfo::root();

qDebug() << storage.rootPath();
if (storage.isReadOnly())
    qDebug() << "isReadOnly:" << storage.isReadOnly();

qDebug() << "name:" << storage.name();
qDebug() << "fileSystemType:" << storage.fileSystemType();
qDebug() << "size:" << storage.bytesTotal()/1000/1000 << "MB";
qDebug() << "availableSize:" << storage.bytesAvailable()/1000/1000 << "MB";

Code has been copied from the example in QT 5.5 docs



回答2:

The new QStorageInfo class, introduced in Qt 5.4, can do this (and more). It's part of the Qt Core module so no additional dependencies required.

#include <QStorageInfo>
#include <QDebug>

void printRootDriveInfo() {
   QStorageInfo storage = QStorageInfo::root();

   qDebug() << storage.rootPath();
   if (storage.isReadOnly())
       qDebug() << "isReadOnly:" << storage.isReadOnly();

   qDebug() << "name:" << storage.name();
   qDebug() << "filesystem type:" << storage.fileSystemType();
   qDebug() << "size:" << storage.bytesTotal()/1000/1000 << "MB";
   qDebug() << "free space:" << storage.bytesAvailable()/1000/1000 << "MB";
}


回答3:

There is nothing in Qt at time of writing.

Consider commenting on or voting for QTBUG-3780.



回答4:

I wrote this back when I wrote the question (after voting on QTBUG-3780); I figure I'll save someone (or myself) from doing this from scratch.

This is for Qt 4.8.x.

#ifdef WIN32
/*
 * getDiskFreeSpaceInGB
 *
 * Returns the amount of free drive space for the given drive in GB. The
 * value is rounded to the nearest integer value.
 */
int getDiskFreeSpaceInGB( LPCWSTR drive )
{
    ULARGE_INTEGER freeBytesToCaller;
    freeBytesToCaller.QuadPart = 0L;

    if( !GetDiskFreeSpaceEx( drive, &freeBytesToCaller, NULL, NULL ) )
    {
        qDebug() << "ERROR: Call to GetDiskFreeSpaceEx() failed.";
    }

    int freeSpace_gb = freeBytesToCaller.QuadPart / B_per_GB;
    qDebug() << "Free drive space: " << freeSpace_gb << "GB";

    return freeSpace_gb;
}
#endif

Usage:

// Check available hard drive space
#ifdef WIN32
        // The L in front of the string does some WINAPI magic to convert
        // a string literal into a Windows LPCWSTR beast.
        if( getDiskFreeSpaceInGB( L"c:" ) < MinDriveSpace_GB )
        {
            errString = "ERROR: Less than the recommended amount of free space available!";
            isReady = false;
        }
#else
#    pragma message( "WARNING: Hard drive space will not be checked at application start-up!" )
#endif


回答5:

I need to write to a mounted USB-Stick and I got the available size of memory with the following code:

QFile usbMemoryInfo;
QStringList usbMemoryLines;
QStringList usbMemoryColumns;

system("df /dev/sdb1 > /tmp/usb_usage.info");
usbMemoryInfo.setFileName( "/tmp/usb_usage.info" );

usbMemoryInfo.open(QIODevice::ReadOnly);

QTextStream readData(&usbMemoryInfo);

while (!readData.atEnd())
{
    usbMemoryLines << readData.readLine();
}

usbMemoryInfo.close();

usbMemoryColumns = usbMemoryLines.at(1).split(QRegExp("\\s+"));
QString available_bytes = usbMemoryColumns.at(3);


回答6:

I know that this question is already quite old by now, but I searched stackoverflow and found that nobody got solution for this, so I decided to post.

There is QSystemStorageInfo class in QtMobility, it provides cross-platform way to get info about logical drives. For example: logicalDrives() returns list of paths which you can use as parameters for other methods: availableDiskSpace(), totalDiskSpace() to get free and total drive's space, accordingly, in bytes.

Usage example:

QtMobility::QSystemStorageInfo sysStrgInfo;
QStringList drives = sysStrgInfo.logicalDrives();

foreach (QString drive, drives)
{
    qDebug() << sysStrgInfo.availableDiskSpace(drive);
    qDebug() << sysStrgInfo.totalDiskSpace(drive);
}

This example prints free and total space in bytes for all logical drives in OS. Don't forget to add QtMobility in Qt project file:

CONFIG += mobility
MOBILITY += systeminfo

I used these methods in a project I'm working on now and it worked for me. Hope it'll help someone!



回答7:

this code`s working for me:

#ifdef _WIN32 //win
    #include "windows.h"
#else //linux
    #include <sys/stat.h>
    #include <sys/statfs.h>
#endif


bool GetFreeTotalSpace(const QString& sDirPath, double& fTotal, double& fFree)
{
    double fKB = 1024;

    #ifdef _WIN32

        QString sCurDir = QDir::current().absolutePath();
        QDir::setCurrent(sDirPath);

        ULARGE_INTEGER free,total;

        bool bRes = ::GetDiskFreeSpaceExA( 0 , &free , &total , NULL );

        if ( !bRes )
            return false;

        QDir::setCurrent( sCurDir );

        fFree = static_cast<__int64>(free.QuadPart)  / fKB;
        fTotal = static_cast<__int64>(total.QuadPart)  / fKB;

    #else // Linux

        struct stat stst;
        struct statfs stfs;

        if ( ::stat(sDirPath.toLocal8Bit(),&stst) == -1 )
            return false;

        if ( ::statfs(sDirPath.toLocal8Bit(),&stfs) == -1 )
            return false;

        fFree = stfs.f_bavail * ( stst.st_blksize / fKB );
        fTotal = stfs.f_blocks * ( stst.st_blksize / fKB );

    #endif // _WIN32

    return true;
}