【问题标题】:How to determine how much free space on a drive in Qt?如何确定 Qt 驱动器上有多少可用空间?
【发布时间】:2009-11-14 00:16:22
【问题描述】:

我正在使用 Qt,并且想要一种独立于平台的方式来获取可用磁盘空间。

我知道在 Linux 中我可以使用 statfs,而在 Windows 中我可以使用 GetDiskFreeSpaceEx()。我知道 boost 有办法,boost::filesystem::space(Path const & p)

但我不想要那些。我在 Qt 中,希望以一种对 Qt 友好的方式来做。

我看了QDirQFileQFileInfo——什么都没有!

【问题讨论】:

  • 接受它并使用Windows API,它是怪物。
  • 看来我还得处理 Linux 版本。喜悦。
  • 总是有APR

标签: c++ qt filesystems


【解决方案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中的示例复制

【讨论】:

  • 世界变得更好了。谢谢,@mr.coffee
  • "...仍然有人发现它很有用。"到目前为止有四个人!
  • @VioletGiraffe 别是果冻,你的答案不一样,你已经编辑它是一样的:P 干杯
【解决方案2】:

Qt 5.4 中引入的新QStorageInfo 类可以做到这一点(以及更多)。它是 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 发表评论或投票。

    【讨论】:

    • 很遗憾,自从我从 2004/2005 年发现的邮件列表帖子以来,这一切都没有改变。在 Qt 的网站上投票。
    • 现在是 Qt 5.4+ 的一部分!
    【解决方案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
    

    【讨论】:

    • ...它不是 Qt 友好的方式 :) 不是跨平台的
    • @FeritCubukcuoglu 绝对不是,但它在当时是有效的。最近有一篇新帖子使用了 Qt 5.5 的一些新功能;现在是公认的答案。
    【解决方案5】:

    我需要写入已安装的 USB 记忆棒,并且我使用以下代码获得了可用的内存大小:

    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,发现没有人解决这个问题,所以我决定发布。

      QtMobility中有QSystemStorageInfo类,它提供了跨平台获取逻辑驱动器信息的方式。例如:logicalDrives() 返回路径列表,您可以将其用作其他方法的参数:availableDiskSpace()totalDiskSpace() 以获取相应的可用空间和总驱动器空间(以字节为单位)。

      使用示例:

      QtMobility::QSystemStorageInfo sysStrgInfo;
      QStringList drives = sysStrgInfo.logicalDrives();
      
      foreach (QString drive, drives)
      {
          qDebug() << sysStrgInfo.availableDiskSpace(drive);
          qDebug() << sysStrgInfo.totalDiskSpace(drive);
      }
      

      此示例打印操作系统中所有逻辑驱动器的可用空间和总空间(以字节为单位)。不要忘记在 Qt 项目文件中添加 QtMobility

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-01
          • 1970-01-01
          • 2016-09-23
          • 1970-01-01
          相关资源
          最近更新 更多