Обсуждение статьи "Работаем с ZIP-архивами средствами MQL5 без использования сторонних библиотек" - страница 9
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Скачал и распаковал почти 300 файлов. А данных в них все больше и достиг предела по размеру.
Файл должен быть с 1,8 млрд char элементов, а распаковывается обрезанным до 1,5 млрд. Часть данных теряется. Странно, что так коротко обрезается, массивы могут иметь до 2147483647 элементов.
Разобрался с файлами (распакованными) превышающими некий объем (для разных файлов от 1,7Гб до 2136507776 - т.е. почти до MAX_INT=2147483647, а массивы не могут иметь больше элементов) и которые на выходе получаются обрезанными. Оказалось, что все они отмечены, как ошибочные при:
Т.е. выходное значение = 0.
Но CZIP это не контролирует. Сделал обнуление размера выходного массива.
Так в моих функциям могу со 100% гарантией определять, что файл успешно распакован.
До этого проверял правильный конец JSON файла }\r\n - но это решение не универсально и кажется несколько файлов из ~1000 были случайно обрезаны по промежуточной строке и были приняты. как успешно распакованные, но в них данные - не полные.
Новый вариант функции:
Желтым выделено новое.
Возможно разработчикам стоит тоже обнулять массив, ведь обрезанные данные вряд ли нужны кому-то. И могут привести к трудно уловимым ошибкам.
Разобрался с файлами (распакованными) превышающими некий объем (для разных файлов от 1,7Гб до 2136507776 - т.е. почти до MAX_INT=2147483647, а массивы не могут иметь больше элементов) и которые на выходе получаются обрезанными. Оказалось, что все они отмечены, как ошибочные при:
Т.е. выходное значение = 0.
Но CZIP это не контролирует. Сделал обнуление размера выходного массива.
Так в моих функциям могу со 100% гарантией определять, что файл успешно распакован.
До этого проверял правильный конец JSON файла }\r\n - но это решение не универсально и кажется несколько файлов из ~1000 были случайно обрезаны по промежуточной строке и были приняты. как успешно распакованные, но в них данные - не полные.
Новый вариант функции:
Желтым выделено новое.
Возможно разработчикам стоит тоже обнулять массив, ведь обрезанные данные вряд ли нужны кому-то. И могут привести к трудно уловимым ошибкам.
Во-первых, возвращаемое значение 0 не является 100% признаком ошибки (это наверно осталось со времен, когда функция использовалась только для шифрования, но не сжатия - вероятно надо бы поменять, но вряд ли будут делать, чтобы не повредить обратную совместимость) для распаковки zip, т.к. zip чисто технически позволяет заархивировать пустые данные ("массив-приемник" будет пустым правомерно, без всякой ошибки).
Во-вторых, наличие частично распакованных данных может быть полезно для диагностики ошибок и потому их лучше оставить.
Во-первых, возвращаемое значение 0 не является 100% признаком ошибки
С моими ~1000 файлами метка с 0 - позволила отбросить все файлы, которые я искал по шаблону конца файла (т.е. сработало на 100%) и еще штук 5, которые видимо по концу строки были обрезаны.
Так что это надежнее, чем мой способ.
В моем случае как раз осталось около 5 обрезанных файлов, которые закончились так же, как ожидаемый конец файла и которые больше нельзя никак проверить - т.е. это не диагностика ошибок, а пропуск ошибки в рабочий алгоритм.
Ваши варианты диагностики ошибок?
Впрочем для себя я решил вопрос. Но ошибки пропускались, пока не разобрался с чужим кодом. Если бы было обнуление на стороне MT, то их не было бы.
ПС. Можно -1 добавить для ошибки с zip, при файле 0-й длины.В общем есть аргументы за и против. Разработчики решат что лучше/логичнее.
В моем случае как раз осталось около 5 обрезанных файлов, которые закончились так же, как ожидаемый конец файла и которые больше нельзя никак проверить - т.е. это не диагностика ошибок, а пропуск ошибки в рабочий алгоритм.
Ваши варианты диагностики ошибок?
Впрочем для себя я решил вопрос. Но ошибки пропускались, пока не разобрался с чужим кодом. Если бы было обнуление на стороне MT, то их не было бы.
Я не понял, как ошибки могли пропускаться. Функция возвращала не ноль и заполненный массив с частично отсутствующими данными из архива? Тогда это баг MQL5 - там должны поправить.
Флаг _LastError проверялся?
На "ожидаемый конец файла" ни в коем случае нельзя закладываться, т.к. архивирование - штука обобщенная - мы можем не знать формата принимаемого файла.
Я не понял, как ошибки могли пропускаться.
Это недоработка библиотеки CZIP из статьи. Проверка на результат распаковки не производилась. Было просто
Только сегодня я нашел это и добавил эту проверку см. выделенное желтым.
Вначале пользования я не знал, что нет проверки - потому и придумал свою проверку на ожидаемый конец файла.
Согласен, потому и сделал обнуление массива при ошибке.
Это самое универсальное, что можно сделать, кроме случая с 0-м размером файла.
Но и при 0-м файле я и обрабатывать/разбирать JSON не буду и никто не будет - просто циклы по элементам не будут запускаться, если число элементов=0, так что обнуление массива, на мой взгляд - хорошее решение.
Встретился архив, который CZip не смог распаковать. При этом 7ZIP и архиватор Винды распаковывают без проблем.
Начал искать где он расчитывается, и нашел в функции FindZipFileSize().Распечатал размер сжатых данных - оказалось на десятки мегабайт меньше архива (а в нем только 1 файл).
Поэкспериментировал...
Оказалось что если вернуть, как размер данных все данные end_size - то архив распаковывается правильно. Видимо при распаковке код сам определяет конец данных, а не полагается на ответ из этой функции. Главное, чтобы не было меньше. Можно было оставить так, но получается, что функция бесполезна, а это вряд ли. И возможно какие-то другие архивы будут сбоить..
Еще 1 эксперимент показал, что если закоментировать строки
То архив тоже начинает распаковываться. Количество данных приблизилось к 100%
Получается, что в архиве имеется uint cdheader = 0x504b0102; и это часть сжатых данных, а не метка их конца.Вы не ошиблись с меткой? В интеренте поиском нашел такую метку. Может ее как то по другому надо обрабатывать, а не обрезать данные по ней, у меня обрезалось 30МБ.
Файл архива могу скинуть в личку, если есть интерес разобраться.Рабочая с этим файлом функция: (файл \Include\Zip\Zip.mqh)
Дело в том, что есть формат Zip, который точно регламентирован и описан, а есть различные упаковщики (windows, total commander, 7zip и т.д.), которые болт забили на этот стандарт и каждый очень творчески подходит к заполнению структур-заголовков. Поэтому CZip не может полагаться на корректно правильный заполненный формат, и рассчитывает что можно самостоятельно. Что там с идентификатором 0x504b0102 надо разбираться.
Надо выполнить ревизию кода еще раз и выкатить рабочее обновление, учитывающее ваши ценные замечания. Рад, что кто-то пользуется либой.
В приложении небольшая доработка кода библиотеки под новые реалии (b5223+) MQL5.
Спасибо. MQL5 все бессмысленней и беспощадней.
99% ошибок удалось бы избежать, если бы MetaQuotes наконец-то внедрила бы штатные функции рефлексии и сериализации.
Встретился архив, который CZip не смог распаковать. При этом 7ZIP и архиватор Винды распаковывают без проблем.
...
Файл архива могу скинуть в личку, если есть интерес разобраться.Скиньте пожалуйста файл архива мне в личку.
Скиньте пожалуйста файл архива мне в личку.
https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-01-18_BTCUSDT_ob500.data.zip
тут в теле архива (не в заголовке) присутствует cdheader = 0x504b0102;
В следующем по дате файле тоже. Думаю часто встречается.
header = 0x504b0304; есть в каждом файле именно в заголовке, т.е. первые 4 символа.
Но он же встречался и в теле архива, редко. Сейчас поищу.
Тут https://quote-saver.bycsi.com/orderbook/linear/BTCUSDT/2023-03-15_BTCUSDT_ob500.data.zip
Думаю надо поиск этих заголовков делать только между телами архивов.