Здравствуйте! Мне нужно распаковать данные, сжатые zlib. Как можно узнать размер распакованных данных? Ведь в C нужно заранее выделять память. В Python это проще сделать: a = zlib.decompress(data_zlib), в Си дело обстоит иначе. Также хочу отметить, что я работаю не с архивами, где размер распакованных данных вроде как указан.
Чтобы узнать размер папки со всеми ее файлами и подкаталогами (размер распакованных данных), можно воспользоваться следующим кодом:
Цитата
void FolderSize(AnsiString Folder,int &Size,int &fCount,int &folCount) { // Функция записывает в параметры: // Size - размер папки в байтах //fCount - общее количество файлов в папке //folCount - общее количество подпапок в папке
TSearchRec SR; // Проверяем, заканчивается ли путь к папке на \, // если да, то удаляем его if(Folder[Folder.Length()] == '\\') Folder.SetLength(Folder.Length()-1); // Делаем первый поиск if(FindFirst(Folder+"\\*.*",faAnyFile,SR) == 0) do { //Если то что мы нашли не является обратными ссылками... if(SR.Name != "." && SR.Name != "..") { // Если то что мы нашли является папкой, // функция вызывает саму себя // и увеличивает счетчик кол-ва подпапок if((SR.Attr & faDirectory)!=0) { FolderSize(Folder+"\\"+SR.Name,Size,fCount,folCount); folCount++; } else { // Если это файл - прибавляем его размер к общему размеру Size = Size + SR.Size; fCount++; } } } while(FindNext(SR)==0); FindClose(SR); }
PATCH1, что-то я не очень понял, при чём тут папки и каталоги? Наверное, вы меня не так поняли. Попытаюсь объяснить свою ситуацию. Есть файл test.dat. В нём записана следующая информация: 4 байта - размер сжатых данных, дальше - данные сжатые zlib. Мне нужно распаковать эти данные, но я не знаю размер, который у меня получится после распаковки. А он мне нужен для выделения памяти.
int uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen); Декомпрессирует исходный буфер в буфер назначения. sourceLen содержит длину в байтах исходного буфера. Перед вызовом функции, destLen должен содержать максимальный размер буфера назначения, который должен быть достаточно большим, чтобы вместить полностью несжатые данные. (Размер несжатых данных должен быть предварительно сохранен компрессором и передан декомпрессору посредством других способов, описание которых выходит за рамки данной библиотеки.) После вызова функции, destLen содержит актуальный размер несжатых данных. Эта функция может быть использована для всего файла за один проход, если этот файл спроецирован в память.
Saitei, я не могу этого сделать. Это посторонние файлы, которые мне нужно распаковать. У меня уже есть распаковщик на Python, но я хотел попробовать на C переписать. Уже весь нет облазил, ничего толкового не нашёл...
Ну а как ты его тогда узнать то собираешься? Посмотри какие коды ошибок эта функция может возвращать... там есть такой, который говорит, что размер буфера недостаточен. Собственно, в большинстве случаев compression ratio не превышает 100%, поэтому просто берешь размер упакованного файла, помноженный на 2 и пытаешься распаковать. Если тебе говорят, что не влезает, то снова умножаешь на 2 и так пока не влезет. C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
Archido, то есть всё это загнать в while или сделать рекурсию, и просто увеличивать память? В принципе, я так и собирался сделать, просто думал есть более лучшее решение. Но всё равно спасибо!
Archido, то есть всё это загнать в while или сделать рекурсию, и просто увеличивать память? В принципе, я так и собирался сделать, просто думал есть более лучшее решение. Но всё равно спасибо!
Да, так тоже можно. Но чтобы эта игра с памятью не сильно ударила по производительности, то советую сделать memory pool