2

cur_file.size return 0, how I can solve this problem?

void MainWindow::setDirectory() {
QString directory_way = QFileDialog::getExistingDirectory(0, "Choose directory: ", "");
QFile cur_file(directory_way);
QFile fileOut("fileout.txt");
if(fileOut.open(QIODevice::WriteOnly | QIODevice::Text))
{
        QTextStream writeStream(&fileOut);
        writeStream << "You chose directory: " << directory_way <<" with size " << cur_file.size();
        fileOut.close();
}}
SanekTNT
  • 21
  • 1
  • 2
  • The file you just created and the buffer not flushed before you close it, so it's size must be zero. – Yu Jiaao Dec 17 '17 at 11:08
  • So, what must I do? – SanekTNT Dec 17 '17 at 11:11
  • Possible duplicate of [How can I find the size of all files located inside a folder?](https://stackoverflow.com/questions/15495756/how-can-i-find-the-size-of-all-files-located-inside-a-folder) – p-a-o-l-o Dec 17 '17 at 17:59

2 Answers2

8

QFile::size() is meant to be used with files only, it can't calculate the size of a directory. Qt does not provide a function to do the latter out of the box, but it is not hard to write your own recursive function that iterates through the directory's files and directories, and adds their sizes...

Here is a complete example:

#include <QtWidgets>

qint64 dirSize(QString dirPath) {
    qint64 size = 0;
    QDir dir(dirPath);
    //calculate total size of current directories' files
    QDir::Filters fileFilters = QDir::Files|QDir::System|QDir::Hidden;
    for(QString filePath : dir.entryList(fileFilters)) {
        QFileInfo fi(dir, filePath);
        size+= fi.size();
    }
    //add size of child directories recursively
    QDir::Filters dirFilters = QDir::Dirs|QDir::NoDotAndDotDot|QDir::System|QDir::Hidden;
    for(QString childDirPath : dir.entryList(dirFilters))
        size+= dirSize(dirPath + QDir::separator() + childDirPath);
    return size;
}

QString formatSize(qint64 size) {
    QStringList units = {"Bytes", "KB", "MB", "GB", "TB", "PB"};
    int i;
    double outputSize = size;
    for(i=0; i<units.size()-1; i++) {
        if(outputSize<1024) break;
        outputSize= outputSize/1024;
    }
    return QString("%0 %1").arg(outputSize, 0, 'f', 2).arg(units[i]);
}

int main(int argc, char* argv[]) {
    QApplication a(argc, argv);

    QString directoryPath = QFileDialog
            ::getExistingDirectory(nullptr, "Choose directory: ", "");
    //calculate and output selected directory size
    qint64 size = dirSize(directoryPath);
    qInfo() << formatSize(size);

    QTimer::singleShot(0, &a, &QApplication::quit);
    return a.exec();
}
Mike
  • 8,055
  • 1
  • 30
  • 44
  • Thank you so much! – SanekTNT Dec 17 '17 at 12:05
  • @SanekTNT, you are welcome. if that is what you are looking for, please edit your question and make it as minimal as possible (i.e. remove the noise related to outputting the result to a file, this is not related to calculating the size of a directory) and accept this answer. A future reader does not have to read the irrelevant code in your question :) – Mike Dec 17 '17 at 12:20
  • Can i get directory size without recursion? – SanekTNT Dec 17 '17 at 13:13
  • @SanekTNT , well, you need to iterate through all sub-directories, sub-sub-directories, ...etc. A recursive function is the simplest way to do so, but you can definitely convert recursion to iteration. Why would you need to do that anyway? – Mike Dec 17 '17 at 13:22
  • I must make program, which displays file system (size of start-directory and files, dirs which included in start-directiory and their sizes). And if we start from C:// , for example, it takes long time, because recursion is slow, that's why can we don't use recursion? – SanekTNT Dec 17 '17 at 13:44
  • It is not because of recursion being slow, it is because processing every file in a whole partition is slow (especially if that partition is C:). I don't think that there is a faster approach to calculate the size of an ordinary directory (even windows explorer takes some time to calculate the size of say `C:\Program Files\`), but if you are aiming to calculate free and used space for a complete disk, win32 functions like `GetDiskFreeSpace` and `GetVolumeInformation` might be more efficient options. – Mike Dec 17 '17 at 13:57
  • I need not only disk C analyse, but any other directory too, and build file system diagram. Exists function, which take size of any directory without recursion? – SanekTNT Dec 17 '17 at 14:04
  • @SanekTNT, again, recursion is not the bottleneck here, it is the fact that you are analyzing every single file in the directory. I don't think that there are other options for you, but you can ask that as a follow-up question, put the `dirSize` function in it, and state how much time does it take for you, and if there are more efficient implementations :) – Mike Dec 17 '17 at 14:53
0

From the Qt documentation of QIODevice::size():

If the device is closed, the size returned will not reflect the actual size of the device.

mschmidt
  • 2,740
  • 4
  • 17
  • 31