Как определить, сколько свободного места на диске в Qt?

Я использую Qt и хочу независимый от платформы способ получить доступное свободное место на диске.

Я знаю в Linux, я могу использовать statfs, а в Windows я могу использовать GetDiskFreeSpaceEx(). Я знаю, что у boost есть способ, boost::filesystem::space(Path const & p).

Но я не хочу этих. Я в Qt и хотел бы сделать это с помощью Qt-friendly.

Я посмотрел на QDir, QFile, QFileInfo - ничего!

Ответы

Ответ 1

Я знаю, это довольно старая тема, но кто-то еще может найти ее полезной.

Так как QT 5.4, то QSystemStorageInfo прекращается, вместо этого существует новый класс QStorageInfo, который делает всю задачу простой и кросс-платформенной.

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

Код был скопирован из примера в QT 5.5 docs

Ответ 2

Новый класс QStorageInfo, представленный в Qt 5.4, может сделать это (и даже больше). Он является частью модуля Qt Core, поэтому никаких дополнительных зависимостей не требуется.

#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()/1024/1024 << "MB";
   qDebug() << "free space:" << storage.bytesAvailable()/1024/1024 << "MB";
}

Ответ 3

В Qt нет ничего в момент написания.

Рассмотрите возможность комментировать или голосовать за QTBUG-3780.

Ответ 4

Я написал это назад, когда я написал вопрос (после голосования на QTBUG-3780); Я полагаю, что я спасу кого-то (или самого себя) от этого с нуля.

Это для 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

Использование:

// 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

Мне нужно записать на установленный USB-Stick, и я получил доступный размер памяти с помощью следующего кода:

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

Я знаю, что этот вопрос уже довольно старый, но я искал stackoverflow и обнаружил, что для этого не было решения, поэтому я решил опубликовать.

Существует класс QSystemStorageInfo в QtMobility, он обеспечивает кросс-платформенный способ получения информации о логических дисках. Например: logicalDrives() возвращает список путей, которые вы можете использовать в качестве параметров для других методов: ДоступноDiskSpace(), totalDiskSpace(), чтобы получить свободного и полного объема диска, соответственно, в байтах.

Пример использования:

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

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

Этот пример печатает свободное и общее пространство в байтах для всех логических дисков в ОС. Не забудьте добавить QtMobility в файл проекта Qt:

CONFIG += mobility
MOBILITY += systeminfo

Я использовал эти методы в проекте, над которым я сейчас работаю, и это сработало для меня. Надеюсь, это поможет кому-то!

Ответ 7

этот код работает для меня:

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