Russian Qt Forum
Ноябрь 26, 2024, 00:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: QZipReader или как распаковать zip  (Прочитано 22965 раз)
NortT
Гость
« Ответ #15 : Июнь 26, 2011, 15:51 »

Гм.. Сделал архив qzipом. Результат:
Код:
"test/" 1 0 0 0 
"test/pict.jpg" 0 1 0 9229
"test/test.odt" 0 1 0 18527
И теперь как таковая распаковка происходит, но в каталог назначения записывается только test/, а в сам test/ ничего не записывается, т.к. да, пермишины.
Записан
NortT
Гость
« Ответ #16 : Июнь 26, 2011, 17:02 »

В общем подправил немного под свои нужды. В конструкторе class GZipWriterPrivate : public QZipPrivate исправил:
Код
C++ (Qt)
permissions(QFile::ReadOwner | QFile::WriteOwner)
на
Код
C++ (Qt)
permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)
это позволило сохранять нужные(?) права на каталог.
И еще при тестировании под виндой нашел один баг(?) с сепаратором в QZipWriter::addDirectory:
Код
C++ (Qt)
   if (!name.endsWith(QDir::separator()))
       name.append(QDir::separator());
Так у меня не работает. В создаваемом каталоге появляется файл нулевой длины. Под виндой такой архив распаковывается нормально. Под линем при распаковке к каталогу добавляется виндовый "\". Вместо QDir::separator() сделал просто "/".
« Последнее редактирование: Июнь 26, 2011, 17:06 от NortT » Записан
ритт
Гость
« Ответ #17 : Июнь 26, 2011, 17:13 »

действительно, нужно
Код:
name = QDir::fromNativeSeparators(name);
if (!name.endsWith(QLatin1Char('/'))
    name += QLatin1Char('/');
посмотрел у себя - там исправлено...

> permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)
так неправильно. нужно так:
Код:
#ifndef FILE_ATTRIBUTE_READONLY
#  define FILE_ATTRIBUTE_READONLY 0x1
#endif
#ifndef FILE_ATTRIBUTE_DIRECTORY
#  define FILE_ATTRIBUTE_DIRECTORY 0x10
#endif

enum HostOS {
    HostFAT      = 0,
    HostAMIGA    = 1,
    HostVMS      = 2,  // VAX/VMS
    HostUnix     = 3,
    HostVM_CMS   = 4,
    HostAtari    = 5,  // what if it's a minix filesystem? [cjh]
    HostHPFS     = 6,  // filesystem used by OS/2 (and NT 3.x)
    HostMac      = 7,
    HostZ_System = 8,
    HostCPM      = 9,
    HostTOPS20   = 10, // pkzip 2.50 NTFS
    HostNTFS     = 11, // filesystem used by Windows NT
    HostQDOS     = 12, // SMS/QDOS
    HostAcorn    = 13, // Archimedes Acorn RISC OS
    HostVFAT     = 14, // filesystem used by Windows 95, NT
    HostMVS      = 15,
    HostBeOS     = 16, // hybrid POSIX/database filesystem
    HostTandem   = 17,
    HostOS400    = 18,
    HostOSX      = 19
};

void QZipPrivate::fillFileInfo(int index, QZipReader::FileInfo &fileInfo) const
{
    FileHeader header = fileHeaders.at(index);
    fileInfo.filePath = QString::fromLocal8Bit(header.file_name);
    quint32 mode = readUInt(header.h.external_file_attributes);
    const HostOS hostOS = HostOS(readUShort(header.h.version_made) >> 8);
    switch (hostOS) {
    case HostUnix:
        mode = (mode >> 16) & 0xffff;
        if (S_ISDIR(mode))
            fileInfo.isDir = true;
        else if (S_ISREG(mode))
            fileInfo.isFile = true;
        else if (S_ISLNK(mode))
            fileInfo.isSymLink = true;
        fileInfo.permissions = modeToPermissions(mode);
        break;
    case HostFAT:
    case HostNTFS:
    case HostHPFS:
    case HostVFAT:
        fileInfo.permissions |= QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther;
        if ((mode & FILE_ATTRIBUTE_READONLY) == 0)
            fileInfo.permissions |= QFile::WriteOwner | QFile::WriteUser | QFile::WriteGroup | QFile::WriteOther;
        if ((mode & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
            fileInfo.isDir = true;
            fileInfo.permissions |= QFile::ExeOwner | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther;
        } else {
            fileInfo.isFile = true;
        }
        break;
    default:
        return; // we don't support anything else
    }
    fileInfo.crc32 = readUInt(header.h.crc_32);
    fileInfo.size = readUInt(header.h.uncompressed_size);
    fileInfo.lastModified = readMSDosDate(header.h.last_mod_file);
}
Записан
ритт
Гость
« Ответ #18 : Июнь 26, 2011, 17:15 »

кстати, из
struct Q_GUI_EXPORT FileInfo
нужно убрать Q_GUI_EXPORT (у Вас может быть другой другой макрос - не суть, его нужно убрать)
Записан
NortT
Гость
« Ответ #19 : Июнь 26, 2011, 18:06 »

Так у меня не работает. Если распаковывать архив с правильными пермишинами, то создается только структура каталогов, файлы не извлекаются. Если попытаться запаковать, то пермишины становятся неправильными (у каталогов и файлов только rw, а х нету).
Записан
ритт
Гость
« Ответ #20 : Июнь 26, 2011, 18:29 »

код выше относится только к чтению - к упаковке отношения не имеет.
а что вывод `qDebug()<<list.at(i).filePath << list.at(i).isDir << list.at(i).isFile << list.at(i).isSymLink << list.at(i).size;` кажет?
Записан
NortT
Гость
« Ответ #21 : Июнь 26, 2011, 19:02 »

код выше относится только к чтению - к упаковке отношения не имеет.
а что вывод `qDebug()<<list.at(i).filePath << list.at(i).isDir << list.at(i).isFile << list.at(i).isSymLink << list.at(i).size;` кажет?
Я не про Ваш код, а про свою правку конструктора:
> permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner)
так неправильно. нужно так:
...
Если из конструктора убрать QFile::ExeOwner, то запаковывается неправильно соответственно распаковать нельзя.
Если распаковываю правильный архив то получаю:
Код:
"tests/" 1 1 0 0 
"tests/img/" 1 1 0 0
"tests/tests.xml" 0 1 0 7512
Первые две записи - каталоги, последняя - файл, но при распаковке создаются только каталоги:
Код:
$ ls  -R ~/Desktop/t/
/home/nortt/Desktop/t/:
tests

/home/nortt/Desktop/t/tests:
img

/home/nortt/Desktop/t/tests/img:
Записан
NortT
Гость
« Ответ #22 : Июнь 27, 2011, 12:31 »

В общем взял QZip из исходников Qt 4.7.3. Все заработало. До этого были исходники из odf-редактора с qt-apps.org, просто сразу я не подозревал, что это есть в исходниках Qt. Я думал это велосипед odf-редактора и пытался прикрутить его к своему проекту, убив два дня на это Улыбающийся
P.S. 2Константин, спасибо за помощь.
Записан
ритт
Гость
« Ответ #23 : Июнь 27, 2011, 13:20 »

пожалуйста. а код из поста http://www.prog.org.ru/index.php?topic=16992.msg125330#msg125330 всё же советую прикрутить...
Записан
NortT
Гость
« Ответ #24 : Июль 03, 2011, 10:20 »

При сборке проекта под виндой возникли проблемы:
Цитировать
c:\QtSDK\Desktop\Qt\4.7.3\mingw\lib/libQtGui4.a(d000607.o)Грустный.text+0x0): multiple definition of `QZipReader::QZipReader(QString const&, QFlags<QIODevice::OpenModeFlag>)'
./release\qzip.o:qzip.cpp:(.text+0x788): first defined here
Под линем собирается без ошибок. Что нужно сделать?
Записан
NortT
Гость
« Ответ #25 : Июль 03, 2011, 13:22 »

А все придумал, заюзал namespace.
Записан
ритт
Гость
« Ответ #26 : Май 16, 2012, 11:05 »

патч, упоминавшийся ранее, залит в 5.0. чуть позже ещё залью.
поддержку экстра-блоков пока отложу до лучших времён...
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.136 секунд. Запросов: 21.