QFileInfo size () возвращает размер ярлыка TARGET - PullRequest
0 голосов
/ 21 ноября 2018

Я сканирую размер папки следующим образом:

qint64 dirSize = 0;
int fileCount = 0;

for(QDirIterator itDir(someDir, QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::System,
                       QDirIterator::Subdirectories);
    itDir.hasNext(); )
{
    itDir.next();
    dirSize += itDir.fileInfo().size();
    ++fileCount;
}

Кажется, это работает нормально.

Однако я заметил, что папка, содержащая ярлыки Windows (.lnk), возвращаетгораздо больший размер, чем ожидалось.Причина в том, что возвращаются размеры целевых ярлыков, а не сами файлы ярлыков.

Но в соответствии с документацией QFileInfo :

В Windows символические ссылки (ярлыки) представляют собой файлы .lnk.Указанный размер () соответствует символической ссылке (а не ее цели) [...]

Итак, мой вопрос: что я здесь не так делаю?Как получить размер файла ярлыка?

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

@ Ответ Роба работает в большинстве случаев, но возвращает 0, если цель ярлыка не существует / недействительна.
Принимая подсказку из этого подхода, вы также можете скопировать ярлык и изменить расширение.

Таким образом, объединяя все это в функцию (я предполагаю, что открытие цели дешевле / безопаснее, чем копирование ярлыка):

qint64 getFileSize(const QString &path)
{
    qint64 size = 0;
    QFileInfo fileInfo(path);

    if(fileInfo.isSymLink() && fileInfo.size() == QFileInfo(fileInfo.symLinkTarget()).size())
    {
        // Try this approach first
        QFile file(path);
        if(file.exists() && file.open(QIODevice::ReadOnly))
            size = file.size();
        file.close();

        // If that didn't work, try this
        if(size == 0)
        {
            QString tmpPath = path+".tmp";
            for(int i=2; QFileInfo().exists(tmpPath); ++i) // Make sure filename is unique
                tmpPath = path+".tmp"+QString::number(i);

            if(QFile::copy(path, tmpPath))
            {
                size = QFileInfo(tmpPath).size();
                QFile::remove(tmpPath);
            }
        }
    }
    else size = fileInfo.size();

    return size;
}
0 голосов
/ 21 ноября 2018

Для целей тестирования я создал ярлык одного из DLL-файлов Qt.Я поместил этот ярлык в пустую папку.Я также создал ярлык sdktool.exe в Qt и поместил его в ту же папку.

Я также заметил, что size () возвращает размер фактического файла, а не размер ярлыка.Я помню, что у меня было похожее поведение в моем старом проекте, и я открыл файл перед чтением размера.

for (QDirIterator itr(someDir, QDir::NoDotAndDotDot|QDir::Files|QDir::Hidden|QDir::System,
                      QDirIterator::Subdirectories); itr.hasNext();) {
    itr.next();

    // Shows wrong size
    qDebug() << itr.fileName() << ", size (unopened): " << itr.fileInfo().size();

    QFile file(itr.filePath());
    if (file.exists() && file.open(QIODevice::ReadOnly)) {
        // Now the size shows correctly
        qDebug() << "Size when opened: " << file.size();
        file.close();
    }
}

Выводы:

"sdktool.lnk" , size (unopened):  2817024
Size when opened:  1325
"test.lnk" , size (unopened):  4429312
Size when opened:  951

Свойство файла Windows 10окно показывает, что размер "test.lnk" составляет 951 байт, а размер "sdktool.lnk" - 1325 байт.

...