Вот кусок кода, он использует классический TZCompressionStream в этом коде есть грубейшая ошибка, там даже желтым выделено две проблемных строки. В кратце на обьект стрима вешается интерфейс вызовом AutoDestroy а потом производится сжатие вызовом ZStream.CopyFrom.
ВАЖНЫЙ НЮАНС!!!!
Чуть выше по коду в dest была произведена запись 4 байт с размером непакованых данных и сжатые данные должны писаться после этих 4 байт.
Попробуйте предположить что в этом коде не так?
Дам подсказку - в деструкторе TZCompressionStream есть финализация кадра
короче, раз ни у кого предположений нет, суть проблемы заключается в VCL реализации TZCompressionStream. Дело в том что TZCompressionStream.CopyFrom не гарантирует полное сжатие данных, он пишет в результирующий стрим только те данные, которые влезли в целый кадр, а хвост записывается в деструкторе. И вот тут и есть проблема. На стрим повесили автодестрой, он скопировал то что влезло по кадрам, НО!!! Но деструктор не вызвался, а позиция dest стрима была поправлена, поэтому хвост архива запишется на финализации процедуры по нулевому оффсету, таким макаром полностью похерив сами сжатые данные.
Да, и это тоже, просто коллега обратился мол чет не работает, а я уже запарился им говорить что не юзайте ваши автодестрои и шаред птр-ы почем зря если не гарантируете что все будет работать как надо
ну поглядывать надо, бесспорно. абсолютно хорошо автоматом мало что работает
Никогда не нужно использовать авторазрушение в работе с ресурсами. В интерфейсах ввели интерфейс IDisposal, где есть метод Dispose для завершения и зарытия всех ресурсов не зависимо от того, когда вызовется деструктор.
есесно не корректно применяется, только сходу это сложно отследить
Обсуждают сегодня