Функции zip файлов (только для чтения)


Содержание

Особенности работы с ZIP- объектами

Платформа 1С:Предприятие предоставляет возможности работы с ZIP архивами. Для этого в системе существуют объекты Запись ZIP Файла , ответственный за запись, и Чтение ZIP Файла , соответственно ответственный за чтение архивов.

Создание ZIP- архивов

Для того чтобы записать файлы в ZIP -архив необходимо выполнить несколько простых действий:

  • Создать архив с необходимыми параметрами, в который будут помещаться файлы.
  • Поместить в архив необходимые файлы.
  • Записать архив.

Рассмотрим эти действия подробнее.

Создание объекта Запись ZIP Файла можно осуществить двумя путями — создать инициализированный объект или создав неинициализированный объект вызвать у него метод Открыть . В обоих случаях состав параметров является одинаковым. В самом простом случае требуется указать только имя файла, куда будет записан архив.

Для создания нового архива требуется указать:

  1. Имя файла, куда будет записан архив. Этот параметр является обязательным. Если такой файл уже существует на диске, он будет перезаписан!
  2. Пароль доступа к архиву. Если этот параметр пропущен или равен пустой строке, то шифрование производится не будет!
  3. Комментарий к архиву.
  4. Метод сжатия файлов в архиве. На выбор предоставляется возможность скопировать файлы в архив без сжатия или сжать их. По умолчанию файлы сжимаются.
  5. Уровень сжатия файлов в архиве. Можно выбирать между минимальным, оптимальным и максимальным сжатием. По умолчанию используется оптимальное сжатие
  6. Метод шифрования. Можно защитить архив методом шифрования ZIP 2.0 , совместимым с большинством программ, или с помощью шифрования на основе новейшего стандарта AES с различной длиной ключа (128, 192 и 256 бит). Однако следует помнить , что данный метод может быть не совместим с некоторыми программами архивирования, например WinRAR .

После создания объекта необходимо добавить в него необходимые файлы, воспользовавшись методом Добавить . Он принимает на вход 3 параметра:

  1. Полное имя файла или маску.
  2. Режим сохранения путей к файлу. Можно сохранять полные пути, не сохранять пути совсем или сохранять пути относительно каталога.
  3. Режим обработки подкаталогов. Можно обрабатывать подкаталоги рекурсивно или не обрабатывать их. Параметр имеет смысл, если в качестве имени указана маска.

После того, как все необходимые файлы добавлены, можно записать архив на диск, воспользовавшись методом Записать() .

Важно понимать , что до выполнения этого метода, никаких реальных действий по созданию архива не происходит. После записи архива на диск объект закрывает его и для работы со следующим архивом необходимо выполнить метод Открыть() .

Особенности упаковки файлов по маске

Остановимся подробнее на особенностях упаковки файлов по маске.

Предположим, что у нас есть следующий файлы, которые нам необходимо поместить в архив:

Пример 1

Мы хотим создать в архив с помощью нижеследующих команд:

В результирующий архив будут помещены следующие файлы:

Пример 2

Мы хотим создать в архив с помощью нижеследующих команд:

В результирующий архив будут помещены следующие файлы:

Пример 3

Мы хотим создать в архив с помощью нижеследующих команд:

В результирующий архив будут помещены следующие файлы:

Чтение ZIP- архивов

Для того чтобы прочитать файлы из ZIP -архива необходимо выполнить несколько простых действий:

  • Открыть необходимый архив
  • Распаковать файлы

Рассмотрим эти действия подробнее.

Создание объекта Чтение ZIP Файла можно осуществить двумя путями — создать инициализированный объект или создав неинициализированный объект вызвать у него метод Открыть() . В обоих случаях состав параметров является одинаковым. В самом простом случае требуется указать только имя архивного файла, с которым необходимо работать.

Для открытия архива требуется указать:

  1. Имя файла, который требуется открыть. Этот параметр является обязательным.
  2. Пароль доступа к архиву.

После того, как архив успешно открыт, можно получить информацию о файлах, хранящихся внутри него. Для этого у объекта Чтение ZIP Файла предусмотрено свойство Элементы , которое предоставляет доступ к коллекции элементов ZIP файла.

Для каждого элемента можно получить разнообразную информацию о его имени, времени его модификации, его атрибутах, а также узнать является ли данный элемент зашифрованным.

После получения информации о элементах их можно распаковать на диск. Это возможно сделать двумя методами:

  • Воспользоваться методом ИзвлечьВсе() .
  • Воспользоваться методом Извлечь() .

Метод ИзвлечьВсе() распаковывает все файлы в архиву по указанному пути. Второй параметр данного метода определяет возможность восстановления исходных путей файлов.

Метод Извлечь() распаковывает указанный элемент коллекции из свойства Элементы по указанному пути. Второй параметр данного метода аналогичен тому же параметру метода ИзвлечьВсе() . Наибольший интерес представляет третий параметр данного метода — Пароль . В нем можно указать индивидуальный пароль для элемента архива, в случае если он зашифрован паролем отличным от других файлов.

После того, как архив нам больше не нужен можно завершить работу с ним вызвав метод Закрыть() .

Дополнительные возможности

При работе с большими объемами данных могут возникнуть проблемы при пересылке архивных файлов. Типичной такой ситуацией является ограничение некоторых почтовых серверов на размер сообщения — если письмо превышает некий заранее установленный размер, оно отбрасывается сервером. Применительно к 1С:Предприятию такая ситуация может возникнуть при пересылке больших сообщений обмена данными.

Для решения этих проблем можно использовать функции РазделитьФайл() и ОбъединитьФайлы() .

Функция РазделитьФайл() предназначена для разбиения файла на несколько частей указанного размера. Функция ОбъединитьФайлы() объединяет несколько файлов в один.

Более подробную информацию о этих функциях можно получить в документации.

Открытие файлов ZIP и видимость файлов в файловой системе

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Сообщений [ 8 ]

1 Тема от antonzh 04-08-2015 13:00:13

  • antonzh
  • New user
  • Неактивен


  • Зарегистрирован: 04-08-2015
  • Сообщений: 3

Тема: Открытие файлов ZIP и видимость файлов в файловой системе

Вчера купил данное устройство 2015 года и столкнулся со следующими проблемами:
1. Не открываются файлы zip, хотя заявлено что должны открываться. Название архива и файла fb2 внутри него на латинице. Пример файла во вложении.
2. Поставил программу DropSync для автосинхронизации с DropBox. Все работает файлы синхронизируются с папкой Documents, но загруженные файлы становятся видны только после перезагрузки устройства.

2 Ответ от Support_Walera 04-08-2015 13:21:40

  • Support_Walera
  • Administrator
  • Неактивен
  • Зарегистрирован: 28-11-2011
  • Сообщений: 11,483

Re: Открытие файлов ZIP и видимость файлов в файловой системе

Не открываются файлы zip, хотя заявлено что должны открываться.

Будут открываться если установите файл менеджер с поддержкой архивов, например ES Проводник, и будете открывать книги из него.

загруженные файлы становятся видны только после перезагрузки устройства.

Странно это. DropBox не пользуюсь. Пользовался Яндекс.Диском — таких проблем не было. Пробовали другим файл менеджером посмотреть?

3 Ответ от antonzh 04-08-2015 14:48:27

  • antonzh
  • New user
  • Неактивен
  • Зарегистрирован: 04-08-2015
  • Сообщений: 3

Re: Открытие файлов ZIP и видимость файлов в файловой системе

Установка ES Проводника в принципе конечно помогла но все равно с архивами получается работать тяжело. В книгах архивы все равно не видны, нужно зайти в проводник, выбрать архив, после чего откроется ES Проводник, в нем нужно выбрать файл из архива, далее выбрать открыть как текст, после чего еще и выбрать программы для чтения. Планируется ли упростить процесс?

4 Ответ от Support_Walera 04-08-2015 16:02:43

  • Support_Walera
  • Administrator
  • Неактивен
  • Зарегистрирован: 28-11-2011
  • Сообщений: 11,483

Re: Открытие файлов ZIP и видимость файлов в файловой системе

Планируется ли упростить процесс?

На этапе обсуждения. Хотелось, чтобы в проводнике показывались обложки книг, а в случае с архивами это затруднено.. Книги в архивах были актуальны, когда было мало места на устройствах для чтения, сейчас вроде нет такой проблемы.

5 Ответ от antonzh 04-08-2015 16:14:21

  • antonzh
  • New user
  • Неактивен
  • Зарегистрирован: 04-08-2015
  • Сообщений: 3

Re: Открытие файлов ZIP и видимость файлов в файловой системе

Книги в формате fb2 тоже не всегда содержат обложку и тогда они кстати на главном экране в строке недавно добавленных не отличаются друг от друга, потому как подписи есть только в недавно прочитанных. А архивы актуальны потому что книги скачанные с интернет сайтов практически всегда запакованы в архивы. Кому нужна красота те их распакуют, а кому нет те будут читать так.

6 Ответ от Support_Walera 04-08-2015 17:14:34


  • Support_Walera
  • Administrator
  • Неактивен
  • Зарегистрирован: 28-11-2011
  • Сообщений: 11,483

Re: Открытие файлов ZIP и видимость файлов в файловой системе

тогда они кстати на главном экране в строке недавно добавленных не отличаются друг от друга, потому как подписи есть только в недавно прочитанных.

Есть приложение Книги, а в нём 3 варианта отображения. В случае с архивами конечно тоже можно раскрывать архивы и отображать обложки, но это сильно нагрузит процессор и замедлит работу файлового менеджера.

7 Ответ от bird 04-08-2015 19:12:50

  • bird
  • New user
  • Неактивен
  • Зарегистрирован: 15-04-2015
  • Сообщений: 8

Re: Открытие файлов ZIP и видимость файлов в файловой системе

Антон, а может проще поставить тот же AllReader, он напрямую может работать с zip архивами.

8 Ответ от Support_Walera 04-08-2015 19:36:06

  • Support_Walera
  • Administrator
  • Неактивен
  • Зарегистрирован: 28-11-2011
  • Сообщений: 11,483

Re: Открытие файлов ZIP и видимость файлов в файловой системе

может проще поставить тот же AllReader, он напрямую может работать с zip архивами.

Тоже вариант, но желательно адаптированную под A6LHD версию — http://4pda.ru/forum/index.php?showtopi p=39864213

Сообщений [ 8 ]

Чтобы отправить ответ, вы должны войти или зарегистрироваться

Работа с zip-архивами в PHP

Уже долгие годы самым распространенным форматом сжатия данных, является формат ZIP. Данный формат широко используется в разработках под web. Поэтому многие языки для web-программирования имеют либо встроенные средства или возможности подключения необходимых библиотек для работы с zip-архивами.

Непосредственно в самом PHP функций для распаковки и создания zip-архивов нету. Хотя это зависит, от вариантов его сборки. Но они присутствуют в PHP расширении “php_zip”. И именно оно позволяет работать с архивными zip-файлами.

Распаковка архива

С распаковкой архивов при веб разработке, приходиться сталкиваться наиболее часто, нежели при разработке прикладного ПО. Особенно когда возникает необходимость в пакетной загрузке данных (документы, сертификаты и т.д.). Ведь даже диалоговое окно для открытия файла в браузере, не имеет возможности мульти выбора файлов. Конечно, можно воспользоваться каким-либо flash-загрузчиком, но во многих ситуациях это не подходит. А значит остается всего один вариант – архивация данных. Для работы по распаковке архива есть ряд функций встроенных в расширение php_zip:

Закрывает архивный zip-файл. Параметр zip обязан быть zip-архивом, открытым до этого функцией zip_open().

Закрывает вхождение директории, специфицированное параметром zip_entry . Параметр zip_entry обязан быть правильным вхождением директории, открытым функцией zip_entry_open().

int zip_entry_filesize (resource $zip_entry )

Возвращает фактический размер вхождения директории zip_entry. Параметр zip_entry обязан быть правильным вхождением директории, открытым функцией zip_read().

string zip_entry_name (resource $zip_entry )

Возвращает имя вхождения директории zip_entry. Параметр zip_entry обязан быть правильным вхождением директории, открытым функцией zip_read().

bool zip_entry_open (resource $zip , resource $zip_entry [, string $mode ])

Открывает вхождение директории в zip-файле для чтения. Параметр zip это правильный дескриптор ресурса, возвращённый функцией zip_open(). Параметр zip_entry это ресурс вхождения директории, возвращённый функцией zip_read(). Необязательный параметр mode может быть одним из режимов, специфицированных в документации для fopen().

Примечание: в настоящее время mode игнорируется и всегда имеет значение “rb”.Это из-за тог, что zip поддерживается в PHP с доступом только для чтения. Возвращает true при успехе, false при неудаче. В отличие от fopen() и других подобных функций, возвращаемое значение функции zip_entry_open() указывает только на результат операции и не нужно для чтения или закрытия вхождения директории.

string zip_entry_read (resource $zip_entry [, int $length ])

Читает до length байтов из открытого вхождения директории. Если параметр length не специфицирован, Функция zip_entry_read() пытается прочитать 1024 байта. Параметр zip_entry является правильным вхождением директории, возвращённым функцией zip_read(). Возвращает прочитанные данные, или false, если достигнут конец файла.


Примечание: параметр length должен быть несжатым размером, который вы хотите прочитать.

resource zip_open (string $filename )

Открывает новый zip-архив для чтения. Параметр filename это имя файла открываемого zip-архива. Возвращает дескриптор ресурса для дальнейшего использования в zip_read() и zip_close(), или возвращает false, если filename не существует.

resource zip_read (resource $zip )

Читает следующее вхождение в файле zip-архива. Параметр zip обязан быть zip-архивом, открытым ранее функцией zip_open(). Возвращает ресурс вхождения директории для дальнейшего использования с zip_entry_… () функциями.

int zip_entry_compressedsize(resource $zip_entry )

Параметр zip_entry обязан быть правильным вхождением директории, открытым функцией zip_read(). Возвращает сжатый размер вхождения директории zip_entry.

string zip_entry_compressionmethod (resource $zip_entry )

Параметр zip_entry обязан быть правильным вхождением директории, открытым функцией zip_read(). Возвращает метод сжатия для вхождения директории zip_entry.

Ниже приведен найденный и модифицированный мной исходный код функции для распаковки архива. Данная функция производит распаковку архива в корневой каталог. Поэтому если есть необходимость в создании директории для последующего расположения в ней распакованных файлов и каталогов, то ее требуется слегка изменить.

Выше был продемонстрирован классический пример распаковки архива. Обратите внимание на то, что указанный к архиву путь, должен быть абсолютным. Но тем не менее существует еще одна возможность, чтобы его распаковать. Для этого нужно прибегнуть к помощи методов класса ZipArchive. Этот класс находится все в том же расширении “php_zip”. Итак для того чтобы применить другой вариант распаковки, необходимо написать следующий код:

Для распаковки архива у данного класса используется только один метод:

bool extractTo (string $destination [, mixed $entries ])

Будущая директория местонахождения распакованного архива задается в параметре $destination . Параметр $entries содержит элементы для извлечения. Он является необязательным и может принимать как одно значение, так и массив значений.

Второй вариант выглядит намного красивее и компактнее, чем первый, не так ли? Поэтому я свой выбор остановил именно на нем. И напоследок протестируем оба варианта на скорость распаковки архива объемом в 205Mb:

Создание архива

Создание архива происходит сложнее, чем его распаковка. Если конечно требуется создать архив с одним файлом или одной директорией, то здесь все просто. А вот если упаковывать директории с неограниченным уровнем вложенности каталогов, то здесь уже придется немного подумать. Во-первых, необходим хороший рекурсивный алгоритм для обхода директорий. Во-вторых, нужно дополнительно хранить локальное имя файла/каталога. Итак, для создания архива нам понадобятся четыре метода класса ZipArchive:

    bool addEmptyDir (string $dirname )

Добавляет в архив пустую директорию. Параметр dirname должен содержать имя директории. Метод в случае успеха возвращает true или false в противном случае.

vo >$filename [, string $localname = NULL [, int $start = 0 [, int $length = 0 ]]])

Добавляет в архив файл, который находится по указанному в параметре filename пути. Параметр localname отвечает за имя файла в архиве. И если он указан, то параметр filename будет переопределен. Параметры start и length , зарезервированы для будущих целей. Данный метод так же в случае успеха возвращает true или false в случае ошибки.

vo >$filename [, int $flags ])

Данный метод необходим для открытия нового архива с целью: чтения, записи или создания. Параметр filename должен содержать имя архива. Необязательный параметр flags используется в качестве режима открытия файла (ZIPARCHIVE::OVERWRITE, ZIPARCHIVE::CREATE, ZIPARCHIVE::EXCL, ZIPARCHIVE::CHECKCONS). Метод возвращает true в случае успеха или код ошибки (см. предопределенные константы ошибок).

vo >Этот метод закрывает открытый или созданный архив и сохраняет изменения. Данный метод автоматически вызывается в конце сценария.

Ниже приведен исходный код созданного класса, позволяющего производить создание zip-архивов:

Данный класс позволяет создавать архив из каталогов с неограниченным уровнем вложенности. Для создания архива, необходимо вызвать только один метод ToZip.

    bool ToZip (string $source , string $destination )

Создает zip-архив. В параметре source требуется указать путь к каталогу или файлу, который требуется запаковать. А в качестве параметра destination передается имя будущего архива. Метод возвращает true в случае успеха или false в случае возникновения ошибки.

Предопределенные константы режима работы

ZIPARCHIVE::CREATE (integer) Создавать архив, если он не существует.
ZIPARCHIVE::OVERWRITE (integer) Всегда создавать новый архив, этот режим перезаписывает файлы, если они существуют.
ZIPARCHIVE::EXCL (integer) Выводить ошибку, если архив существует.
ZIPARCHIVE::CHECKCONS (integer) Выполнять дополнительные проверки на структуру архива, и выдавать ошибку при неудаче.

Предопределенные константы флагов

ZIPARCHIVE::FL_NOCASE (integer) Игнорировать регистр символов в именах элементов архива.
ZIPARCHIVE::FL_NODIR (integer) Не учитывать пути директорий в архиве.
ZIPARCHIVE::FL_COMPRESSED (integer) Читать сжатые данные.
ZIPARCHIVE::FL_UNCHANGED (integer) Использовать исходные данные, игнорируя изменения.

Предопределенные константы методов сжатия

ZIPARCHIVE::CM_DEFAULT (integer) Выбрать лучший метод сжатия deflate или stored (без сжатия).
ZIPARCHIVE::CM_STORE (integer) Метод сжатия stored (без сжатия).
ZIPARCHIVE::CM_SHRINK (integer) Метод сжатия shrunk.
ZIPARCHIVE::CM_REDUCE_1 (integer) Метод сжатия reduced with factor 1.
ZIPARCHIVE::CM_REDUCE_2 (integer) Метод сжатия reduced with factor 2.
ZIPARCHIVE::CM_REDUCE_3 (integer) Метод сжатия reduced with factor 3.
ZIPARCHIVE::CM_REDUCE_4 (integer) Метод сжатия reduced with factor 4.
ZIPARCHIVE::CM_IMPLODE (integer) Метод сжатия imploded.
ZIPARCHIVE::CM_DEFLATE (integer) Метод сжатия deflated.
ZIPARCHIVE::CM_DEFLATE64 (integer) Метод сжатия deflate64.
ZIPARCHIVE::CM_PKWARE_IMPLODE (integer) Метод сжатия PKWARE imploding.
ZIPARCHIVE::CM_BZIP2 (integer) Метод сжатия алгоритмом BZIP2

Предопределенные константы ошибок

Почему мой файл открылся только для чтения?

Примечание: Мы стараемся как можно оперативнее обеспечивать вас актуальными справочными материалами на вашем языке. Эта страница переведена автоматически, поэтому ее текст может содержать неточности и грамматические ошибки. Для нас важно, чтобы эта статья была вам полезна. Просим вас уделить пару секунд и сообщить, помогла ли она вам, с помощью кнопок внизу страницы. Для удобства также приводим ссылку на оригинал (на английском языке) .

Иногда после открытия файла обнаруживается, что он доступен только для чтения. Доступ к файлам может ограничиваться ради безопасности, например при открытии файлов из Интернета, или настраиваться с помощью параметров. Ниже описаны некоторые ситуации, когда файл может быть открыт только для чтения, и возможные варианты действий.

Доступ к файлу ограничивает антивирус

Некоторые антивирусные программы защищают компьютеры от потенциально опасных файлов, открывая их только для чтения. В этом случае вам может потребоваться обратиться за инструкциями к поставщику антивируса. Например, сведения о том, как добавить приложение в исключения в программе Bitdefender, доступны по следующей ссылке: Добавление приложений или процессов в исключения в Центре управления Bitdefender.

Свойства файла настроены для только чтения

Чтобы проверить свойства файла, щелкните его правой кнопкой мыши и выберите пункт Свойства. Если атрибут «только для чтения» установлен, снимите его и нажмите кнопку ОК.

Содержимое просматривается в защищенном режиме

Файлы из Интернета и других потенциально опасных мест могут содержать вирусы, вирусы-червей и другие вредоносные программы, способные причинить вред компьютеру. Заражение также часто происходит при открытии вложений в сообщения электронной почты и скачанных файлов. Для защиты компьютера файлы из таких потенциально опасных мест открываются в защищенном режиме. В этом режиме можно просмотреть содержимое файла с меньшим риском. Дополнительные сведения о защищенном режиме и его настройке см. в статье Что такое защищенный режим?

Хранилище OneDrive заполнено

Если файл хранится в OneDrive и оно заполняется до предела, вы не сможете сохранить документ, пока не освободите для него место. Чтобы узнать, сколько свободного места остается в хранилище OneDrive, щелкните значок OneDrive в центре уведомлений и выберите пункт Управление хранилищем или войдите на сайт http://onedrive.live.com и посмотрите нужное значение в левой нижней части экрана.

Набор Office не активирован

Если Office не активирован или срок вашей подписки истек, доступность файлов только для чтения может быть связана с переходом Office в режим ограниченной функциональности. Сведения о том, как активировать Office, см. в статье Ошибки, связанные с нелицензированным продуктом и активацией Office.

Если устранить проблему не удается.

Установите обновления Office.


Запустите восстановление Office по сети.

Присоединяйтесь к обсуждению

Наши эксперты и участники сообщества обсуждают эту тему на форуме ответов. Щелкните эту ссылку, чтобы перейти туда, почитать обсуждения и поучаствовать в них.

Нам важно ваше мнение

В этой статье последней проверки Бен на 21 июня 2020 , являющееся результатом свои комментарии. Если в этой статье найдено полезны и особенно, если вы не воспользуйтесь элементами управления отзыв внизу для сообщите нам, как сделать ее лучше.

Как снять атрибут «только для чтения» со всех папок и файлов?

Сняв «со всех» — поимеешь ещё больше проблем. Тем более, если «Никогда в жизни не сталкивался». Можешь вообще потерять всю ОСь и данные, как некоторые, особо настырные.

Либо говори — какие конкретно файлы или папки, либо озвучивай в чём сама проблема?!

Это не терминал, это «командная строка» (консоль). Папка программы и все файлы лежат в корне системного диска, естественно, что на эту папку распространяется ограничение прав, но это не атрибут «только для чтения», это именно ограничение для изменения не админом (и не системой).

Решение — либо настраивать права доступа, либо запускать «консоль» от имени администратора. Если это просто проект, то можно дать пользователю под которым работаешь полный доступ к «корневой папке» OpenServer, сделав себя владельцем (в том числе подпапок).

Предотвращение изменениям файла путем включения атрибута «только для чтения»

Предоставление важным или личным файлам атрибута «только для чтения» помогает защитить их от случайных или неавторизованных изменений. Если файл имеет атрибут «только для чтения», его нельзя изменить.

  1. Щелкните правой кнопкой мыши файл, которому нужно предоставить атрибут «только для чтения», и выберите пункт Свойства.
  2. На вкладке Общие установите флажок Только чтение и нажмите кнопку ОК
  3. Если позже возникнет необходимость внести изменения в файл, можно убрать атрибут «только для чтения», сняв флажок Только чтение .

Обозначение папки как доступной только для чтения делает все файлы этой папки доступными только для чтения. Файлы, добавленные позже в папку с атрибутом «только для чтения», не превращаются в файлы доступные только для чтения.

Внимание! В файлы с атрибутом «только для чтения» нельзя вносить изменения, однако их можно копировать, перемещать, переименовывать или удалять. Может случиться, что после перемещения, переименования или удаления файла, доступного только для чтения, программа, связанная с этим файлом, начнет работать некорректно.

Чтение ZIP файла

Алгоритм получения данных из ZIP файла:

  • находим запись EOCD
  • загружаем записи CentralDirectoryFileHeader
  • для каждой CentralDirectoryFileHeader , находим и загружаем LocalFileHeader
  • данные располагаются сразу после LocalFileHeader , иногда размер данных записывается после самих данных в структуру DataDescriptor , об этом сигнализирует флаг generalPurposeBitFlag

Теперь каждый шаг подробнее.

Находим запись EOCD

Эта запись располагается в конце файла. Ее поиск производится от конца файла к началу по сигнатуре. Стартовое место поиска равно размеру файла минус размер структуры EOCD. Если сигнатура не найдена, то смещаемся к началу файла по одному байту за раз.

struct LocalFileHeader < uint32_t signature; uint16_t versionToExtract; uint16_t generalPurposeBitFlag; uint16_t compressionMethod; uint16_t modificationTime; uint16_t modificationDate; uint32_t crc32; uint32_t compressedSize; uint32_t uncompressedSize; uint16_t filenameLength; uint16_t extraFieldLength; >__attribute__((packed)); // Переходим к началу записи is.seekg(cdfh.localFileHeaderOffset, is.beg); // Считываем ее целиком LocalFileHeader lfh; is.read((char *) &lfh, sizeof(lfh)); if (0x04034b50 != lfh.signature) < // Ошибка break; >// Пропускаем название файла is.seekg(lfh.filenameLength, is.cur); // Пропускаем дополнительную информацию is.seekg(lfh.extraFieldLength, is.cur);

Загружаем данные

Для этого шага нам понадобится библиотека zlib, потому что данные сжимаются методом deflate. Как правило, сразу после LocalFileHeader идут данные размером compressedSize . Если данные сжаты, то флаг compressionMethod равен 8 (или Z_DEFLATED ), иначе он нулевой (или Z_STORED ). Сжатые данные необходимо считать во временный буфер размером compressedSize и распаковать с помощью библиотеки zlib в буфер размером uncompressedSize .

Как разархивировать файлы на Andro >

Архив — место для хранения чего-либо. На смартфоне архив выполняет схожую функцию — хранение большого количества файлов в одном месте и сжатом виде.

Пользователю проще собрать множество файлов в один архив и передать, чем прикреплять каждый файл по отдельности. В этом главная задача архива — скачать что-то быстро, в большом количестве и без потерь. Еще и памяти меньше потратить!

Разберемся в сути архивов , их видах и функциях и узнаем, как извлечь запакованные файлы на Android .

Содержание:

1.Виды архивов

Самые распространенные архивы — ZIP и RAR .

Также на базе Андроид используются: 7-Zip, ARJ, CAB, UUE, GZip, ACE и другие, менее известные.

Обычному пользователю достаточно функционала ZIP и RAR . Преимущество их в простоте использования, хорошем базовом функционале и распространенности, т.к. большинство телефонов на базе Android поддерживает данные форматы .

А в чем разница между ними?

В целом, ZIP — проще и быстрее. RAR — обширнее по функционалу и надежнее.

2.Андроид, который поддерживает архивы:

Работать с архивами пользователь андроид может только через специальные приложения. Из-за их огромного разнообразия, скачанная программа сможет поддерживать работу с любыми архивами . Главное — найти подходящую, изучив ее описание со смартфона или планшета.

Распространенные программы поддерживают распаковку и упаковку файлов Android версии 4.0 и выше.

3.Приложения архиваторы:

Архиватор — приложение , позволяющее создавать и распаковывать архивы .

Существует два типа таких программ : архиваторы и проводники .

У проводников огромное количество опций и возможность распознавания очень редких форматов , но без технических знаний в таком приложении не обойтись. Разбираться придется долго.

Обычные же архиваторы выполняют две функции: сжатие и распаковка материалов. Для новичка, базового пользователя — идеальный вариант. Рассмотрим самые популярные архиваторы и узнаем, как с ними работать .

Чтобы скачать архиватор или проводник, достаточно ввести нужное слово в поисковую строку Play Маркет

Рисунок 1. Поиск приложений в Play маркет

Далее идет трудный выбор между проводниками и архиваторами, сложным и простым функционалом. Разберемся в самых популярных:

RAR для Андроида

RAR — популярный и удобный архиватор для Андроида . Часто его хватает для совершения всех необходимых действий.

Функционал : создание RAR и ZIP архивов . Распаковка RAR, ZIP, 7z, GZ, BZ2, XZ, ISO, ARJ, TAR. Восстановление поврежденных архивов (ZIP и RAR). Возможность шифрования. Непрерывные архивы. Создание томов. Использование нескольких ядер процессора для сжатия.

Бесплатность приложения указывает на наличие рекламы, которая покрывает затраты на разработку. Есть возможность отключения рекламы за отдельную плату.

Как создать архив в RAR?

Откройте вкладку «Параметры упаковки» в верхней панели.

Рисунок 2. Как создать архив в RAR

Выберете необходимые параметры и создайте архив. При возникновении вопросов нажмите на кнопку “Помощь”.

Рисунок 3. Параметры упаковки архива в RAR

Как распаковать архив в RAR?

Сначала выберете нужный архив, затем нажмите на вкладку «Параметры распаковки» и следуйте дальнейшей инструкции


Рисунок 4. Как распаковать архив в RAR

ZArchiver:

Также простое в использовании, популярное приложение .

Функционал: создавать архивы : 7z (7zip), zip, bzip2 (bz2), gzip (gz), XZ, tar; Распаковывать архивы: 7zip, zip, rar, rar5, bzip2, gzip, xz, iso, tar, arj, cab, lzh, lha, lzma, xar, tgz, tbz, Z, deb, rpm, zipx, mtz, chm, dmg, cpio, cramfs, img, wim, ecm, arc, lzip. Шифрование. Создание и распаковка многотомных архивов. Частичное извлечение файлов.

Минус: нет поддержки сжатия в формат RAR. Только распаковка.

Работа в этой программе схожа с предыдущим приложением . В целом, интерфейс всех проводников и архиваторов схож между собой. Главное — читать инструкции, обращаться к вкладке “Помощь” и просматривать описание функций в Play Маркет. Рассмотрите основные отличия на рисунке 5.

Работаем с ZIP-архивами средствами MQL5 без использования сторонних библиотек

Оглавление

Введение

Однажды автора данной статьи привлекла интересная особенность функции CryptDecode, а именно — возможность распаковывать переданный ей ZIP-массив. Этот модификатор был введен разработчиками торговой платформы MetaTrader 5 для того, чтобы можно было распаковывать ответ некоторых серверов, используя стандартную функцию WebRequest. Однако из-за некоторых особенностей формата ZIP-файла, использовать ее напрямую было невозможно.

Требовалась дополнительная аутентификация: для распаковки архива необходимо знать его хеш-сумму до упаковки: Adler-32, которой, естественно, не было. Однако, при обсуждении этой проблемы, разработчики пошли навстречу и перегрузили CryptDecode и CryptEncode, ее зеркального близнеца, специальным флагом, игнорирующим хеш Adler32 при распаковке переданных данных. Для неискушенных в техническом плане пользователей это нововведение можно объяснить просто: благодаря ему стала возможной полнофункциональная работа с ZIP-архивами. Эта статья подробно описывает формат ZIP-файла, особенности хранения данных в нем и предлагает для работы с архивом удобный объектно-ориентированный класс CZip.

Для чего это нужно

Сжатие данных — одна из важнейших технологий, особенно распространенная в среде Web. Благодаря сжатию экономятся ресурсы, необходимые для передачи, хранения и обработки информации. Сжатие данных используется практически во всех областях коммуникаций и проникло практически во все задачи, с которыми мы сталкиваемся при работе на компьютере.

Не стала исключением и финансовая сфера: гигабайты тиковой истории, потоки котировок, включая слепки стаканов (Level2-данные), немыслимо хранить в сыром, несжатом виде. Многие серверы, в том числе предоставляющие аналитическую информацию, интересную для торговли, также хранят данных в ZIP-архивах. Раньше не представлялось возможным получать эти данные автоматически, используя штатные средства MQL5. Теперь ситуация изменилась.

С помощью функции WebRequest можно скачать ZIP-архив и на лету распаковать его данные прямо в оперативную память компьютера. Все эти возможности важны и обязательно будут востребованы многими трейдерами. Сжатие данных можно использовать даже для экономии оперативной памяти компьютера. О том, как это делается, посвящен раздел 3.2 данной статьи. Наконец, умение работать с ZIP-архивами открывает доступ к формированию документов типа Microsoft Office по стандарту Office Open XML, что, в свою очередь, сделает возможным создание простых файлов Excel или Word прямо из MQL5, также без использования сторонних DLL библиотек.

Как видно, применение ZIP-архивирования обширно, и класс, создаваемый нами, сослужит хорошую службу всем пользователям MetaTrader.

В первой главе данной статьи мы подробно опишем собственно формат ZIP-файла и поймем, из каких блоков данных он состоит. Данная глава будет интересна не только тем, кто изучает MQL, она также послужит хорошим образовательным материалом и тем, кто занимается изучением вопросов, связанных с архивированием и хранением данных. Вторая глава будет посвящена классам CZip, CZipFile и CZipDirectory — эти классы являются основными объектно-ориентированными элементами для работы с архивом. Третья глава описывает практические примеры, связанные с использованием архивирования. Четвертая глава является документацией к предлагаемым классам.

Итак, приступим к изучению этого самого распространенного типа архивирования.

Глава 1. Формат ZIP-файла и способ хранения данных в нем


1.1. Структура ZIP-файла

Формат ZIP был создан Филом Кацом в 1989 году и впервые был реализован в программе PKZIP для MS-DOS, выпущенной компанией PKWARE, основателем которой являлся Кац. Этот формат архива наиболее часто использует алгоритм сжатия данных DEFLATE. Наиболее распространенными программами для работы с этим форматом в среде Windows являются WinZip и WinRAR.

Важно понимать, что формат ZIP-архива развивался со временем и имеет несколько версий. В создании класса для работы с ZIP-архивом, мы будем опираться на официальную спецификацию формата версии 6.3.4, размещенную на сайте компании PKWARE по адресу: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT. Это последняя спецификация формата, датируемая 1 октября 2014 года. Сама спецификация формата достаточно обширна и включает описания множества нюансов.

В данной статье мы будем исходить из принципа наименьших усилий и создадим инструмент, который будет использовать лишь самые необходимые данные для успешной распаковки файлов и создания новых архивов. Это значит, что в определенной мере работа с ZIP-файлами будет ограничена — совместимость форматов не гарантируется, а значит, и не приходится говорить о полной «всеядности» архивов. Вполне возможно, что некоторые ZIP-архивы, созданные сторонними средствами, не смогут быть распакованы с помощью предложенного инструмента.

Каждый ZIP-архив — это бинарный файл, содержащий упорядоченную последовательность байтов. С другой стороны, в ZIP-архиве каждый файл имеет имя, атрибуты (например время модификации файла) и другие свойства, которые мы привыкли видеть в файловой системе любой операционной системы. Поэтому, помимо запакованных данных, каждый ZIP-архив хранит имя запакованного файла, его атрибуты и другую служебную информацию. Эта служебная информация располагается в строго определенном порядке и имеет регулярную структуру. Например, если в архиве содержатся два файла (File#1 и File#2), то архив будет иметь следующую схему:

Рис. 1. Схематичное представление ZIP-архива, содержащего два файла: File#1 и File#2

Позже мы разберем подробно каждый блок данной схемы, а сейчас дадим краткое описание этих блоков:

  • Local File Header — этот блок данных содержит основную информацию о запакованном файле: размер файла до и после упаковки, время модификации файла, контрольную сумму CRC-32 и локальный указатель на имя файла. Кроме того, этот блок содержит версию архиватора, необходимую для распаковки файла.
  • File Name последовательность байтов произвольной длины, образующая имя запакованного файла. При этом длина имени файла не должен превышать 65 536 символов.
  • File Data упакованное содержимое файла в виде байт-массива произвольной длины. Если файл пустой или представляет из себя каталог, то этот массив не используется, и сразу за именем файла или директории идет заголовок Local File Header, описывающий следующий файл.
  • Central Directory содержит расширенное представление данных в Local File Header. Помимо данных, содержащихся в Local File Header, содержит атрибуты файла, локальную ссылку на структуру Local File Header и некоторую другую, в большинстве случаев неиспользуемую информацию.
  • End of central directory record — эта структура представлена в каждом архиве единственным экземпляром и записывается в самый конец архива. Наиболее интересные данные, которые она содержит, это количество записей в архиве (или количество файлов и каталогов) и локальные ссылки на начало блока Central Directory.

Каждый блок данной схемы можно представить либо в виде регулярной структуры, либо в виде байт-массива произвольной длины. Каждую из структур, в свою очередь, можно описать с помощью одноименной конструкции программирования в MQL — структуры.

Структура всегда занимает строго определенное количество байтов, поэтому она не может содержать внутри себя массивы произвольной длины и строки. Однако она может содержать указатели на эти объекты. Именно поэтому названия файлов в архиве вынесены за пределы структуры, благодаря чему они могут иметь произвольную длину. То же относится к упакованным данным файлов — их размер является произвольным, поэтому и они содержатся за пределами структур. Таким образом, можно сказать, что ZIP-архив представляет из себя последовательность структур, строк и упакованных данных.

Формат ZIP-файла, помимо представленного выше, описывает дополнительную структуру, так называемый Data Descriptor. Эта структура используется только в том случае, если по каким-то причинам не удалось сформировать структуру Local File Header, и часть данных, необходимая для Local File Header, стала доступна уже после сжатия данных. На практике это очень экзотическая ситуация, поэтому данная структура практически никогда не используется, и в нашем классе для работы с архивами этот блок данных не поддерживается.

Обратите внимание, что согласно формату ZIP-архива каждый файл сжимается независимо от остальных. С одной стороны, это позволяет локализовать возникновение ошибок: «битый» архив можно восстановить, удалив файл с неправильным содержимым и оставив все остальное содержимое архива без изменений. С другой стороны, при сжатии каждого файла отдельно снижается эффективность сжатия, в особенности если каждый из файлов занимает мало места.

1.2. Изучаем ZIP-файл в шестнадцатеричном редакторе

Теперь, вооружившись самыми необходимыми знаниями, мы можем посмотреть, что находится внутри типичного ZIP-архива. Для этого воспользуемся одним из шестнадцатиричных редакторов, WinHex. Если по каким-то причинам WinHex’а у вас нет, вы можете воспользоваться любым другим шестнадцатиричным редактором. Ведь мы помним, что любой архив — это бинарный файл, который можно открыть как простую последовательность байтов. Для эксперимента создадим простой ZIP-архив, содержащий внутри себя один-единственный текстовый файл с фразой «HelloWorld!» («Привет Мир!»):

Рис. 2. Создание текстового файла в блокноте

Затем воспользуемся любым ZIP-архиватором и с его помощью создадим архив. В нашем примере таким архиватором будет WinRAR. В нем необходимо выбрать только что созданный файл и заархивировать его в формате ZIP:

Рис. 3. Создание архива с помощью архиватора WinRAR

После окончания архивирования на жестком диске компьютера в соответствующей директории появится новый файл «HelloWorld.zip». Первая особенность этого файла которая бросается в глаза — его размер, составляющий 135 байт, он гораздо больше первоначального размера исходного текстового файла в 11 байт. Это связано именно с тем, что помимо собственно упакованных данных, ZIP-архив содержит служебную информацию. Поэтому для небольших данных, занимающих всего несколько сот байтов, архивирование бессмысленно.

Теперь, когда у нас есть схема расположения данных, архив, состоящий из набора байтов, не покажется нам пугающим. Откроем его с помощью шестнадцатеричного редактора WinHex. На рисунке ниже представлен байтовый массив архива с условной подсветкой каждой области, описанной на схеме 1:

Рис. 4. Внутреннее содержимое ZIP-архива, содержащего файл HelloWorld.txt

Собственно фраза «HelloWorld!» содержится в диапазоне с 0x2B по 0x35 байт и занимает всего 11 байт. Обратите внимание, что алгоритм сжатия решил не сжимать исходную фразу, и в ZIP-архиве она присутствует в исходном виде. Это произошло потому, что сжатие такого короткого сообщения неэффективно, и сжатый массив может оказаться даже больше несжатого.

ZIP-архив не во всех случаях содержит сжатые данные. Иногда данные в архиве располагаются в исходном, несжатом виде, даже если при создании архива было явно указано сжимать данные при архивировании. Эта ситуация возникает в случае, когда размер данных незначителен, и сжатие данных неэффективно.

Благодаря рисунку 4 становится понятным, как разные блоки данных хранятся в получившемся архиве, и где именно содержатся данные файла. Теперь настало время подробно разобрать каждый из блоков данных в отдельности.

1.3. Структура Local File Header

Каждый ZIP-архив начинается со структуры Local File Header. Она содержит метаданные файла, следующего за ней в виде сжатого байтового массива. Каждая структура в архиве, согласно спецификации формата, имеет свой уникальный четырехбайтовый идентификатор. Не является исключением и эта структура, ее уникальный идентификатор равен 0x04034B50 .

Важно учитывать, что x86-совместимые процессоры загружают данные из бинарных файлов в оперативную память в обратном порядке. Числа при этом располагаются наизнанку: последний байт занимает место первого и наоборот. Способ записи данных в файл определяется форматом самого файла и для файлов в формате ZIP также осуществляется в обратном порядке. Более подробно о порядке следования байтов можно почитать в одноименной статье на Wikipedia: «Порядок байтов». Для нас же это означает, что идентификатор структуры будет записан в виде числа 0x504B0304 (значения 0x04034B50, вывернутого наизнанку). Именно с этой последовательности байтов начинается любой ZIP-архив.

Поскольку структура — это строго определенная последовательность байтов, ее можно представить в виде аналогичной структуры на языке программирования MQL5. Описание структуры Local File Header на MQL5 будет следующим:

Данная структура используется для реальной работы с ZIP-архивами, поэтому помимо собственно полей данных, содержит дополнительные методы, позволяющие конвертировать структуру в набор байтов (байтовый массив uchar) и, наоборот, создавать структуру из набора байтов. Приведем содержимое методов ToCharArray и LoadFromCharArray, позволяющих делать такое преобразование:

Опишем поля структуры (перечислены в порядке следования):

  • header — уникальный идентификатор стркутуры, для File Local Header равен 0x04034B50 ;
  • version — минимальная версия для распаковки файла;
  • bit_flag — битовый флаг, имеет идентификатор 0x02 ;
  • comp_method — тип используемого сжатия. Как правило, всегда используется метод сжатия DEFLATE, этот тип сжатия имеет идентификатор 0x08 .
  • last_mod_time — время последней модификации файла. Содержит часы, минуты и секунды модификации файла в формате MS-DOS. Этот формат описан на странице компании Microsoft.
  • last_mod_date — дата последней модификации файла. Содержит день месяца, номер месяца в году и год модификации файла в формате MS-DOS.
  • crc_32 — контрольная сумма CRC-32. Используется программами по работе с архивами для определения ошибок содержимого файла. Если это поле не заполнено, ZIP-архиватор откажется распаковывать упакованный файл, ссылаясь на испорченный файл.
  • comp_size — размер в байтах упакованных данных;
  • uncomp_size — размер в байтах исходных данных;
  • filename_length — длина имени файла;
  • extrafield_length — специальное поле для записи дополнительных атрибутов данных. Практически никогда не используется и равно нулю.

При сохранении этой структуры в архиве создается последовательность байтов, хранящая значения соответствующих полей этой структуры. Снова загрузим наш ZIP-архив с файлом HelloWorld.txt в шестнадцатеричный редактор и разберем байтовый массив этой структуры уже подробно:

Рис. 5. Байт-схема структуры Local File Header в архиве HelloWorld.zip

Из схемы видно, какие байты занимают те или иные поля структуры. Для проверки данных в ней обратим внимание на поле «File Name length», оно занимает два байта и равно значению 0x0D00 . Вывернув это число наизнанку и переведя его в десятичный формат, мы получим значение 13 — именно столько символов занимает имя файла «HelloWorld.txt». То же самое можем проделать с полем, указывающим размер сжатых данных. Оно равно 0x0B000000 , что соответствует 11 байтам. В самом деле, фраза «HelloWorld!» хранится в архиве в несжатом виде и занимает 11 байт.

Сразу после структуры идут сжатые данные, а затем начинается новая структура: Central Directory, ее мы опишем более подробно в следующем разделе.

1.4. Структура Central Directory

Структура Central Directory представляет собой расширенное представление данных, находящихся в Local File Header. По сути, для основной работы с ZIP-архивами достаточно данных из Local File Header. Тем не менее, использование структуры Central Directory является обязательным, и ее значения должны быть корректно заполнены. Эта структура имеет свой уникальный идентификатор 0x02014B50 . На MQL5 ее представление будет следующим:

Как видно, она содержит уже больше данных, однако большая часть из них дублирует данные Local File Header. Так же как и предыдущая структура, она содержит сервисные методы по конвертации своего содержимого в байт-массив и обратно.

  • header — уникальный идентификатор структуры, равен 0x02014B50 ;
  • made_ver — версия стандарта архивирования, используемого при архивировании;
  • version — минимальная версия стандарта для успешной распаковки файла;
  • bit_flag — битовый флаг, имеет идентификатор 0x02 ;
  • comp_method — тип используемого сжатия. Как правило, всегда используется метод сжатия DEFLATE, этот тип сжатия имеет идентификатор 0x08 .
  • last_mod_time — время последней модификации файла. Содержит часы, минуты и секунды модификации файла в формате MS-DOS. Этот формат описан на странице компании Microsoft.
  • last_mod_date — дата последней модификации файла. Содержит день месяца, номер месяца в году и год модификации файла в формате MS-DOS.
  • crc_32 — контрольная сумма CRC-32. Используется программами по работе с архивами для определения ошибок содержимого файла. Если это поле не заполнено, ZIP-архиватор откажется распаковывать упакованный файл, ссылаясь на испорченный файл.
  • comp_size — размер в байтах упакованных данных;
  • uncomp_size — размер в байтах исходных данных;
  • filename_length — длина имени файла;
  • extrafield_length — специальное поле для записи дополнительных атрибутов данных. Практически никогда не используется и равно нулю.
  • file_comment_length — длина комментария к файлу;
  • disk_number_start — номер диска, в который записывается архив. Практически всегда равен нулю.
  • internal_file_attr — атрибуты файла в формате MS-DOS;
  • external_file_attr — расширенные атрибуты файла в формате MS-DOS;
  • offset_header — адрес, по которому располагается начало структуры Local File Header.


При сохранении этой структуры в архиве создается последовательность байтов, хранящая значения ее полей. Приведем схему расположения байтов этой структуры, подобно рисунку 5:

Рис. 6. Байт-схема структуры Central Directory в архиве HelloWorld.zip

В отличие от Local File Header, структуры Central Directory идут последовательно друг за другом. Адрес начала первой из них указан в специальном завершающем блоке данных — структуре ECDR. Более подробно эту структуру мы опишем в следующем разделе.

1.5. Структура End of Central Directory Record (ECDR)

Структура End of Central Directory Record (или просто ECDR) завершает ZIP-файл. Ее уникальный идентификатор равен 0x06054B50 . В каждом архиве она содержится в единственном экземпляре. ECDR хранит количество файлов и директорий, находящихся в архиве, а также адрес начала последовательности структур Central Directory и их суммарный размер. Помимо этого, блок данных хранит и другие сведения. Приведем полное описание ECDR на MQL5:

Опишем поля этой структуры более подробно:

  • header — уникальный идентификатор структуры, равен 0x06054B50;
  • disk_number — номер диска;
  • disk_number_cd — номер диска, с которого начинается Central Directory;
  • total_entries_disk — всего записей в секции Central Directory (количество файлов и директорий);
  • total_entries — всего записей (количество файлов и директорий);
  • size_central_dir — размер секции Central Directory;
  • start_cd_offset — байт-адрес начала секции Central Directory;
  • file_comment_length — длина комментария к архиву.

При сохранении этой структуры в архиве создается последовательность байтов, хранящая значения ее полей. Приведем схему расположения байтов этой структуры:

Рис. 7. Байт-схема структуры ECDR

Этот блок данных будет использован нами при определении количества элементов в массиве.

Глава 2. Обзор класса CZip и его алгоритмов

2.1. Структура упакованных файлов в архиве, классы CZipFile и CZipFolder

Итак, в первой главе мы подробно разобрали формат ZIP-архива. Мы рассмотрели, из каких типов данных он состоит, и описали эти типы в соответствующих структурах. Определив эти типы, мы реализуем высокоуровневый специализированный класс CZip, с помощью которого можно будет легко и просто совершать следующие действия с ZIP-архивом:

  • Создавать новый архив;
  • Открывать ранее созданный архив на жестком диске;
  • Загружать архив с удаленного сервера;
  • Добавлять новые файлы в архив;
  • Удалять файлы из архива;
  • Распаковывать архив как полностью, так и отдельные его файлы.

Класс CZip возьмет на себя правильное заполнение необходимых структур в архиве, предоставляя нам привычный высокоуровневый интерфейс для работы с файловой коллекцией архива. Возможностей, предоставляемых классом, будет более чем достаточно для подавляющего большинства задач, связанных с архивированием.

Очевидно, что содержимое ZIP-архива можно разделить на папки и файлы. Оба типа содержимого имеют обширный набор свойств: имя, размер, атрибуты файла, время создания и т.д. Некоторые из этих свойств являются общими как для папок, так и для файлов, а некоторые, как, например, упакованные данные, нет. Поэтому оптимальным решением для работы с архивом будет предоставление специальных служебных классов: CZipFile и CZipDirectory. Именно эти классы будут представлять файлы и папки соответственно. Условная классификация содержимого в архиве приведена на схеме ниже:

Рис. 8. Условная классификация объектов в архиве

Таким образом, чтобы добавить файл в архив CZip, необходимо вначале создать объект типа CZipFile, а затем добавить этот объект-файл в архив. В качестве примера создадим текстовый файл «HelloWorld.txt», содержащий одноименный текст «HelloWorld!» и добавим его в архив:

После выполнения этого кода на диске компьютера появится новый ZIP-архив, содержащий единственный текстовый файл «HelloWorld.txt» с одноименной фразой. Если бы мы захотели создать папку вместо файла, то вместо CZipFile нам необходимо было бы создать экземпляр класса CZipFolder. Для его создания достаточно было бы указать только имя.

Как уже было сказано, классы CZipFile и CZipFolder имеют много общего. Поэтому оба класса наследуются от их общего прародителя — CZipContent. Этот класс содержит общие методы и данные для работы с содержимым архива.

2.2. Создание упакованных файлов с помощью CZipFile

Создание упакованного ZIP-файла тождественно созданию экземпляра CZipFile. Как известно, чтобы создать файл, необходимо указать его имя и содержимое. Поэтому конструктор CZipFile также требует явного указания соответствующих параметров:

В разделе 2.1 был показан вызов именно этого конструктора.

Кроме того, иногда требуется не создавать файл, а загрузить уже имеющийся файл с диска. Для этого случая в классе CZipFile существует второй конструктор, позволяющий создать ZIP-файл на основе обычного файла на жестком диске:

Вся работа в этом конструкторе делегируется приватному методу AddFile. Алгоритм его работы следующий:

  1. Открывается указанный файл для чтения, его содержимое считывается в байт-массив.
  2. Полученный байт-массив упаковывается методом AddFileArray и хранится в специальном динамическом массиве типа uchar.

Метод AddFileArray является «сердцем» всей системы классов для работы с архивами. Ведь именно в этом методе находится самая важная системная функция — CryptEncode. Приведем исходный код этого метода:

Желтым цветом указано конфигурирование функции CryptEncode c последующем архивированием байт-массива. Таким образом, можно сделать вывод, что упаковка файла происходит в момент создания объекта CZipFile, а не в момент создания или сохранения самого ZIP-архива, как можно было бы подумать. Благодаря этому свойству все данные, переданные в класс CZip, автоматически сжимаются, а значит, требуют для своего хранения меньше оперативной памяти.

Обратите внимание, что во всех случаях в качестве данных используется беззнаковый байт-массив uchar. В самом деле, все данные, которыми мы оперируем на компьютере, можно представить как некую последовательность байтов. Поэтому для создания действительно универсального контейнера сжатых данных, чем CZipFile и является по своей сути, был выбран беззнаковый массив uchar.

Пользователю необходимо самостоятельно сконвертировать данные для хранения в архиве в беззнаковый массив uchar[], который, в свою очередь, также необходимо передать по ссылке в качестве содержимого файла для класса CZipFile. Благодаря этой особенности в ZIP-архиве может располагаться абсолютно любой тип файлов, как загруженный с диска, так и созданный в процессе работы MQL-программы.

Распаковка данных является более тривиальной задачей. Для распаковки данных в исходный байт массив file_array используется метод GetUnpackFile, который по сути является методом-обложкой для системной функции CryptDecode:

2.3. Вспоминаем MS-DOS. Формат времени и даты в ZIP-архиве

Формат хранения данных ZIP создавался в конце 80-ых годов прошлого века для платформы MS-DOS, «правопреемником» которой стала Windows. В то время ресурсы для хранения данных были ограничены, поэтому дату и время ОС MS-DOS хранила отдельно: два байта (или машинное слово для 16-разрядных процессоров того времени) выделялось для даты и два байта для времени. Причем самая ранняя дата, которая могла быть представлена этим форматом, была 1 января 1980 года (01.01.1980). Минуты, часы, дни, месяцы и годы занимали определенные диапазоны битов в машинном слове, и для того чтобы извлечь или записать их, по-прежнему приходится прибегать к битовым операциям.

Приведем формат хранения даты в соответствующем двухбайтовом поле:

№ битов Описание
0-4 День месяца (0-31)
5-8 Номер месяца (1 — январь, 2 — февраль и т.д.)
9-15 Номер года начиная с 1980

Таблица 1. Формат хранения даты в двухбайтовом поле

Аналогично, приведем формат хранения времени в соответствующем двухбайтовом поле:

№ битов Описание
0-4 Секунды (точностью хранения +/- 2 секунды)
5-10 Минуты (0-59)
11-15 Часы в 24-часовом формате

Таблица 2. Формат хранения времени в двухбайтовом поле

Зная спецификацию данного формата и умея работать с битовыми операциями, можно написать соответствующие функции, конвертирующие дату и время в формате MQL в формат MS-DOS. Можно также написать обратные процедуры. Такие методы конвертации общие как для папок, представленных CZipFolder, так и для файлов, представленных CZipFile. Задавая таким образом дату и время для них в привычном MQL формате, мы «за кулисами» конвертируем этот тип данных в формат MS-DOS. Таким конвертированием занимаются методы DosDate, DosTime, MqlDate и MqlTime. Приведем их исходный код.

Конвертация даты формата MQL в формат даты MS-DOS:

Конвертация даты в формате MS-DOS в формат MQL:

Конвертация времени формата MS-DOS в формат времени MQL:

Конвертация времени формата MS-DOS в формат времени MQL:

Данные методы используют внутренние переменные для хранения даты и времени: m_directory.last_mod_time и m_directory.last_mod_date, где m_directory — структура типа Central Directory.

2.4. Генерация контрольной суммы CRC-32

Интересной особенностью формата ZIP-архива является хранение, помимо служебных данных, специальной информации для восстановления, которая в некоторых случаях помогает восстановить поврежденные данные. Для того чтобы понять, являются ли полученные данные целыми или поврежденными, в ZIP-архиве содержится специальное дополнительное поле, хранящее двухбайтовое значение специального хеша CRC-32. Это контрольная сумма, которая рассчитывается для данных до упаковки. Архиватор, распаковав данных из архива, заново рассчитывает эту контрольную сумму, и если она не совпадает, считает, что данные повреждены и не могут быть предоставлены пользователю.

Таким образом, нашему классу CZip необходимо иметь свой собственный алгоритм расчета CRC-32. В противном случае архивы, созданные нашим классом, откажутся читать сторонние средства для работы с ними, например WinRAR выдаст ошибку-предупреждение о поврежденных данных:

Рис. 9. Предупреждение архиватора WinRAR о повреждении данных файла «HelloWorld.txt»

Поскольку контрольная сумма CRC-32 требуется только для файлов, метод, рассчитывающий эту сумму, представлен лишь в классе CZipFile. Метод реализован на основе примера на языке программирования Си, приведенного в статье по адресу: https://ru.wikibooks.org/wiki/Реализации_алгоритмов/Циклический_избыточный_код:

Чтобы убедиться в правильности работы метода, достаточно открыть архив, созданный с помощью CZip, в архиваторе WinRAR. Каждый файл будет иметь свой уникальный код CRC-32:

Рис. 10. Контрольная сумма CRC-32 в окне архиватора WinRAR

Файлы с корректным CRC-32 хешем архиватор распаковывает в штатном режиме, без появления соответствующих предупреждающих сообщений.

2.5. Чтение и запись архива


Последнее, что мы разберем, будут методы для чтения и записи самого ZIP-архива. Очевидно, что если у нас есть коллекция, например CArrayObj, состоящая из элементов CZipFile и CZipFolder, задача по формированию самого архива будет тривиальной. Достаточно каждый элемент сконвертировать в байт-последовательность и записать ее в файл. Этими задачами занимаются следующие методы:

  • SaveZipToFile — открывает указанный файл и записывает в него сгенерированный байт-массив архива.
  • ToCharArray — создает соответствующую байтовую структуру архива. Генерирует завершающую структуру ECDR.
  • ZipElementsToArray — преобразует элемент типа CZipContent в последовательность байтов.

Единственная сложность состоит в том, что каждый элемент архива, представленный типом CZipContent, хранится в двух разных частях файла, в структурах Local File Header и Central Directory. Поэтому необходимо использовать специальный вызов метода ZipElementsToArray, который в зависимости от переданного ему модификатора ENUM_ZIP_PART выдает либо байтовый массив типа Local File Header, либо Central Directory.

Теперь, учитывая эту особенность, нам должно быть понятно содержимое этих трех методов, исходный код которых представлен ниже:

Загрузка архива также обладает некоторыми нюансами. Очевидно, что загрузка архива — операция, обратная сохранению. Если при сохранении архива элементы типа CZipContent преобразуются в байтовую последовательность, то при загрузке архива байтовая последовательность преобразуется в элементы типа CZipContent. И снова, из-за того, что каждый элемент в архиве хранится в двух разных частях файла — Local File Header и Central Directory, элемент CZipContent за одно чтение данных создать невозможно.

Необходимо использовать промежуточный класс-контейнер CSourceZip, в который вначале последовательно добавляются нужные элементы, а затем на его основе формируется нужный тип данных — CZipFile или CZipFolder. Именно поэтому эти два класса имеют дополнительный конструктор, принимающий в качестве ссылочного параметра указатель на элемент типа CSourceZip. Данный вид инициализации, как и сам класс CSourceZip, создавался исключительно для служебного использования классом CZip, и его не рекомендуется использовать в явном виде.

За саму загрузку ответственны три метода класса CZip:

  • LoadZipFromFile — открывает указанный файл и читает его содержимое в байт-массив.
  • LoadHeader — загружает по предложенному адресу из байтового массива архива структуру Local File.
  • LoadDirectory — загружает по предложенному адресу из байтового массива архива структуру Central Directory.

Итак, приведем исходный код этих методов:

Глава 3. Примеры использования класса CZip, измерение производительности

В предыдущей главе мы рассмотрели класс CZip и собственно формат данных ZIP-архива. Теперь, зная устройство архива, а также общие принципы работы с классом CZip, мы можем перейти к рассмотрению практических задач, связанных с архивированием. В данной главе подробно рассмотрены три разносторонних примера, которые наиболее полно охватывают весь спектр задач этого класса.

3.1. Создание ZIP-архива с котировками по всем выбранным символам

Первая задача, которую часто требуется решать, это сохранение ранее полученных данных. Часто данные получаются в самом терминале MetaTrader. Такими данными могут быть последовательность накопленных тиков или котировки в формате OHLCV. Мы рассмотрим задачу, когда котировки требуется сохранить в специальные CSV-файлы, формат которых будет следующим:

Это текстовый формат данных. Он часто используется для передачи данных между разными системами статистического анализа. Формат текстовых файлов, к сожалению, обладает большой избыточностью хранения данных, так как в каждом байте используется лишь очень ограниченное количество знаков. Как правило, это знаки пунктуации, цифры, заглавные и строчные буквы алфавита. Кроме того, многие значения в этом формате часто повторяются, например, дата или цена открытия, как правило, одна и та же для большого массива данных. Поэтому сжатие этого типа данных должно быть эффективным.

Итак, давайте напишем скрипт, загружающий необходимые данные из терминала. Его алгоритм будет следующим:

  • Последовательно выбираются инструменты, размещенные в окне Market Watch.
  • По каждому выбранному инструменту запрашиваются котировки для каждого из 21 таймфрейма.
  • Котировки выбранного таймфрейма конвертируются в массив CSV строк.
  • Массив CSV строк конвертируется в байтовый массив.
  • Создается ZIP-файл (CZipFile), содержащий байтовый массив котировок, после чего он добавляется в архив.
  • После создания всех файлов котировок архив CZip сохраняется на диске компьютера в файл Quotes.zip.

Исходный код скрипта, выполняющий эти действия, представлен ниже:

Загрузка данных может занимать существенное время, поэтому в окне Market Watch были выбраны только четыре символа. Кроме того, мы загрузим лишь сто последних известных баров. Это тоже должно сократить время выполнения скрипта. После его выполнения в папке общих файлов MetaTrader появился архив Quotes.zip. Его содержимое можно увидеть в любой программе по работе с архивами, например WinRAR:

Рис. 11. Сохраненные файлы котировок, просматриваемые в архиваторе WinRAR

Созданный архив сжат втрое по сравнению с исходным размером. Об этом нам сообщает сам архиватор WinRAR:

Рис. 12. Степень сжатия сгенерированного архива в информационном окне WinRAR

Это хороший результат сжатия. Однако еще лучшего коэффициента сжатия удалось бы добиться на больших и немногочисленных файлах.

Пример скрипта, создающий котировки и сохраняющий их в zip архив прикреплен к данной статье под именем ZipTask1.mq5 и находится в папке Scripts.

3.2. Загрузка архива с удаленного сервера на примере сайта MQL5.com

Следующая рассматриваемая задача будет сетевой. Наш пример продемонстрирует, как можно загружать ZIP-архивы с удаленных серверов. В качестве примера мы произведем загрузку индикатора Alligator, находящегося в базе исходных кодов Code Base по адресу https://www.mql5.com/ru/code/9:

Для каждого опубликованного в Code Base индикатора, советника, скрипта или библиотеки существует архивная версия, где все исходные коды продукта упакованы в единый архив. Именно эту архивную версию мы скачаем и распакуем на локальном компьютере. Но прежде чем это сделать, необходимо поставить разрешение на доступ к mql5.com, для чего в окне Сервис Настройки Советники необходимо вписать адрес «https://www.mql5.com» в список разрешенных серверов.

Класс CZip обладает собственным методом для загрузки архивов с интернет-ресурсов. Но вместо его использования давайте напишем собственный скрипт, совершающий такую загрузку:

Как видите, исходный код скрипта довольно простой. Вначале вызывается WebRequest с адресом удаленного ZIP-архива. WebRequest закачивает байт-массив архива в результирующий массив zip_array, после чего он загружается в класс CZip посредством метода CreateFromCharArray. Этот метод позволяет создать архив прямо из последовательности байтов, что бывает иногда необходимым при внутренней работе с архивами.

Помимо метода CreateFromCharArray, CZip содержит специальный метод LoadZipFromUrl для загрузки архивов по интернет-ссылке. Он работает примерно так же, как и наш предыдущий скрипт. Приведем его исходный код:

Результат работы этого метода будет аналогичным: через некоторое время будет создан ZIP-архив, содержимое которого будет скачано с удаленного сервера.

Пример скрипта, загружающий архив из CodeBase прикреплен к данной статье под именем ZipTask2.mq5 и находится в папке Scripts.

3.3. Сжатие служебных данных программы в оперативной памяти компьютера

Сжатие внутренних данных программы в оперативной памяти компьютера — нетривиальный способ использования архивирования. Этот способ можно использовать, когда обрабатываемых данных слишком много для размещения в оперативной памяти. Однако при использовании данного подхода общая производительность программы снизится, ведь потребуются дополнительные действия по архивированию/разархивированию служебных структур или данных.

Предположим, что MQL-программе необходимо хранить коллекцию исторических ордеров. Каждый ордер будет описываться специальной структурой Order, которая будет содержать все его свойства: идентификатор, тип ордера, время исполнения, объем и т.д. Опишем данную структуру:

Вызов оператора sizeof показывает, что данная структура занимает 200 байт. Таким образом, хранение коллекции исторических ордеров занимает количество байт, рассчитанное по формуле: sizeof(Order) * количество исторических ордеров. Следовательно, для коллекции, насчитывающей 1000 исторических ордеров, потребуется выделение памяти 200 * 1000 = 200 000 байт или почти 200 Кбайт. Это немного по современным меркам, однако в случае, когда размер коллекции будет превышать десятки тысяч элементов, объем занимаемой памяти будет существенен.

Тем не менее, можно разработать специальный контейнер для хранения этих ордеров, который бы позволял сжимать их содержимое. Этот контейнер, помимо обычных методов добавления и удаления новых элементов Order, также будет содержать методы Pack и Unpack, сжимающие содержимое структур типа Order. Приведем исходный код данного контейнера:

Идея в том, что пользователь может добавлять новые элементы в контейнер, а также, в случае необходимости, сжимать его содержимое прямо в оперативной памяти компьютера. Посмотрим, как это работает. Напишем демонстрационный скрипт:

Момент сжатия коллекции в нем выделен желтым маркером. Запущенный на одном из счетов, насчитывающем 858 исторических ордеров, данный скрипт выдал следующие результаты:

Как видно, размер неупакованной коллекции составил 171 600 байт. После упаковки размер коллекции был равен всего 1 521 байт. Т.е. степень компрессии превысила сто раз! Это объясняется тем, что многие поля структуры содержат похожие данные. Также многие поля имеют пустые значения, под которые, тем не менее, выделяется память.

Чтобы убедиться, что сжатие действительно работает корректно, достаточно выбрать любой ордер из коллекции и распечатать его свойство. Нами был выбран первый ордер и его уникальный идентификатор. После упаковки идентификатор ордера отобразился верно:

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

Интересно, что упаковка 858 элементов занимает около 2.5 миллисекунд на достаточно мощном компьютере. Распаковка этих же данных происходит еще быстрее и занимает порядка 0.9 миллисекунды. Таким образом, на один цикл упаковки/распаковки массива, состоящего из тысячи элементов, тратится примерно 3.5-4.0 миллисекунды. При этом достигается более чем стократная экономия памяти. Такие характеристики смотрятся достаточно впечатляюще, чтобы использовать ZIP-сжатие для организации больших массивов данных.

Пример скрипта, сжимающего данные в оперативной памяти, прикреплен к данной статье под именем ZipTask3.mq5 и находится в папке Scripts. Для его работы также необходим файл Orders.mqh, располагающийся в папке Include.

Глава 4. Документация к классам для работы с ZIP-архивами

4.1. Документация к классу CZipContent

В данной главе описаны методы и перечисления, используемые в классах для работы с ZIP-архивами. На уровне пользователей класс CZipContent не используется напрямую, однако все его открытые методы делегируются классам CZipFile и CZipFolder, таким образом, свойства и методы, описанные в нем, распространяются также и на эти классы.

Метод ZipType возвращает тип текущего элемента в архиве. Типов элементов, хранимых в архиве, два: папка (директория) и файл. Тип папки представлен классом CZipDirectory, тип файла представлен классом CZipFile. Более подробно о типах ZIP-архива можно прочитать в разделе 2.1 текущей главы: «Структура упакованных файлов в архиве, классы CZipFile и CZipFolder».

Возвращает перечисление ENUM_ZIP_TYPE, описывающее, к какому типу принадлежит текущий экземпляр CZipContent.

Возвращает название папки или файла в архиве.

Имя файла или папки.

Метод Name(string name)

Устанавливает название текущей папки или файла в архиве. Используется в случаях, когда требуется изменить имя текущей папки или файла.

  • [in] name — новое имя папки или файла. Имя должно быть уникальным и не иметь совпадений среди других имен папок и файлов в архиве.

Метод CreateDateTime(datetime date_time)

Устанавливает новую дату изменения папки или файла в архиве.


  • [in] date_time — дата и время, которое требуется установить для текущей папки или файла.

Дата и время конвертируются в формат MS-DOS и хранятся во внутренних структурах типа ZipLocalHeader и ZipCentralDirectory. Подробнее о способах конвертирования и представления этого формата описано в разделе 2.3 данной статьи: «Вспоминаем MS-DOS. Формат времени и даты в ZIP-архиве».

Возвращает дату и время изменения текущей папки или файла.

Дата и время изменения текущей папки или файла.

Возвращает размер упакованных данных в файле. Для директорий размер упакованных данных всегда равен нулю.

Размер упакованных данных в байтах.

Возвращает размер исходных, неупакованных данных в файле. Для директорий размер неупакованных данных всегда равен нулю.

Размер исходных данных в байтах.

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

Суммарный размер текущего элемента в архиве, учитывающий дополнительные служебные данные.

Возвращает длину имени директории или файла, выраженную в количестве используемых символов.

Длина имени директории или файла, выраженная в количестве используемых символов.

Распаковывает содержимое элемента и сохраняет его в файле с именем элемента на жестком диске компьютера. Если распаковывается директория, то вместо файла создается соответствующая папка.

  • [in] folder — имя корневой папки, в которую требуется распаковать текущую папку или файл. Если элемент требуется распаковать без создания папки архива, то это значение необходимо оставить пустым, равным «».
  • [in] file_common — этот модификатор указывает, в какой секции файловой системы программ MetaTrader необходимо распаковать элемент. Установите этот параметр равным FILE_COMMON, если хотите выполнить распаковку в общий файловый раздел всех терминалов MetaTrader 5.

Возвращает истину, если распаковка файла или папки на жесткий диск прошла успешно. Возвращает ложь в противном случае.

4.2. Документация к классу CZipFile

Класс CZipFile наследуется от CZipContent и используется для хранения файлов в архиве. CZipFile хранит содержимое файла только в упакованном виде. Это значит, что при передаче ему файла для хранения происходит автоматическая упаковка его содержимого. Распаковка файла также происходит в автоматическом режиме при вызове метода GetUnpackFile. Помимо ряда поддерживаемых методов CZipContent, CZipFile также поддерживает специальные методы для работы с файлами. Далее приведены описания этих методов.

Добавляет файл с жесткого диска в текущий элемент CZipFile. Для того чтобы добавить файл в архив типа CZip, вначале необходимо создать экземпляр класса CZipFile, указав при создании название файла и путь к нему. После того как экземпяляр класса будет создан, его необходимо будет добавить в класс CZip, вызвав соответствующий метод. Фактическая упаковка переданного содержимого происходит в момент его добавления (вызова данного метода).

  • [in] full_path — полное имя файла, включая путь к нему относительно центрального каталога файлов программ MQL.
  • [in] file_common — этот модификатор указывает, в какой секции файловой системы программ MetaTrader необходимо распаковать элемент. Установите этот параметр равным FILE_COMMON, если хотите выполнить распаковку в общий файловый раздел всех терминалов MetaTrader 5.

Возвращает истину, если добавление файл прошло успешно. Возвращает ложь в противном случае.

Добавляет в качестве содержимого CZipFile массив байтов типа uchar. Данный метод используется в случае динамического создания содержимого файла. Фактическая упаковка переданного содержимого происходит в момент его добавления (вызова данного метода).

  • [in] file_src — байтовый массив, который необходимо добавить.

Возвращает истину, если добавление файл прошло успешно. Возвращает ложь в противном случае.

Возвращает упакованное содержимое файла.

  • [out] file_array — байтовый массив, в который требуется принять упакованное содержимое файла.

Возвращает распакованное содержимое файла. Содержимое распаковывается в момент обращения к методу.

  • [out] file_array — байтовый массив, в который требуется принять распакованное содержимое файла.

4.3. Документация к классу CZip

Класс CZip реализует основную работу с архивами типа ZIP. Класс представляет собой обобщенный архив ZIP, в который могут быть добавлены ZIP-элементы двух типов: элементы, представляющие папку (CZipDirectory), и элементы, представляющие ZIP-файлы (CZipFile). Помимо прочего, класс CZip позволяет загружать уже существующие архивы, как с жесткого диска компьютера, так и в виде байт-последовательности.

Конвертирует содержимое ZIP-архива в байтовую последовательность типа uchar.

  • [out] zip_arch — байтовый массив, в который требуется принять содержимое ZIP-архива.

Загружает ZIP-архив из байтовой последовательности.

  • [out] zip_arch — байтовый массив, из которого требуется загрузить содержимое ZIP-архива.

Истина, если создание архива из байтовой последовательности прошло успешно, и ложь в противном случае.

Сохраняет текущий ZIP-архив с его содержимым в указанный файл.

  • [in] zip_name — полное имя файла, включая путь к нему относительно центрального каталога файлов программ MQL.
  • [in] file_common — этот модификатор указывает, в какой секции файловой системы программ MetaTrader необходимо распаковать элемент. Установите этот параметр равным FILE_COMMON, если хотите выполнить распаковку в общий файловый раздел всех терминалов MetaTrader 5.

Истина, если сохранение архива в файл прошла успешно, и ложь в противном случае.

Загружает содержимое архива из файла на жестком диске компьютера.

  • [in] full_path — полное имя файла, включая путь к нему относительно центрального каталога файлов программ MQL.
  • [in] file_common — этот модификатор указывает, в какой секции файловой системы программ MetaTrader необходимо распаковать элемент. Установите этот параметр равным FILE_COMMON, если хотите выполнить распаковку в общий файловый раздел всех терминалов MetaTrader 5.

Истина, если загрузка архива из файла прошла успешно, и ложь в противном случае.

Загружает содержимое архива по интернет-ссылке url. Для корректной работы данного метода необходимо выставить разрешение для доступа к запрашиваемому ресурсу. Более подробно работа этого метода описана в разделе 3.2 данной статьи: «Загрузка архива с удаленного сервера на примере сайта MQL5.com»

Распаковывает все файлы и директории текущего архива в предложенный каталог.

  • [in] folder — папка, в которую необходимо распаковать текущий архив. Если папку для архива создавать не требуется, в качестве параметра необходимо передать пустое значение «».
  • [in] file_common — этот модификатор указывает, в какой секции файловой системы программ MetaTrader необходимо распаковать элемент. Установите этот параметр равным FILE_COMMON, если хотите выполнить распаковку в общий файловый раздел всех терминалов MetaTrader 5.

Истина, если распаковка архива прошла успешно, и ложь в противном случае.

Возвращает размер архива в байтах.

Размер архива в байтах.

Возвращает количество элементов в архиве. Элементом архива может быть директория либо запакованный файл.

Количество элементов в архиве.

Добавляет новый ZIP-файл в текущий архив. Файл должен быть представлен в виде CZipFile и создан предварительно, до добавления в архив.

  • [in] file — ZIP-файл, который требуется добавить в архив.

Истина, если добавление в архив прошло успешно, и ложь в противном случае.

Удаляет файл типа CZipFile по индексу index из архива.

  • [in] index — индекс файла, который требуется удалить из архива.

Истина, если удаление файла из архива прошло успешно. Ложь в противном случае.

Получает элемент типа CZipFile, размещенный по индексу index.

  • [in] index — индекс файла, который требуется получить из архива.

Элемент типа CZipFile, который располагается по индексу index.

4.4. Структура ENUM_ZIP_ERROR и получение расширенной информации об ошибках

В процессе работы с классами CZip, CZipFile и CZipDirectory могут возникать различные ошибки, например ошибка, возникающая при попытке доступа к несуществующему файлу и т.д. Большинство методов, представленных в этих классах, возвращают соответствующий флаг типа bool, сигнализирующий об успешности совершения операции. В случае возвращения отрицательного значения (false) можно получить дополнительную информацию о причинах сбоя. Причинами сбоя могут быть как стандартные, системные ошибки, так и специфические ошибки, возникающие в процессе работы с ZIP-архивом. Для передачи специфических ошибок используется механизм передачи пользовательских ошибок с помощью функции SetUserError. Коды пользовательских ошибок задаются перечислением ENUM_ZIP_ERROR:

Значение Описание
ZIP_ERROR_EMPTY_SOURCE Файл, переданный для упаковки, пустой.
ZIP_ERROR_BAD_PACK_ZIP Ошибка внутреннего упаковщика/распаковщика.
ZIP_ERROR_BAD_FORMAT_ZIP Переданный формат ZIP-файла не соответствует стандарту либо испорчен.
ZIP_ERROR_NAME_ALREADY_EXITS Имя, под которым пользователь пытается сохранить файл, уже используется в архиве.
ZIP_ERROR_BAD_URL Переданная ссылка не ссылается на ZIP-архив, либо доступ к указанному интернет-ресурсу запрещен настройками терминала.

При получении пользовательской ошибки необходимо явно привести ее к перечислению ENUM_ZIP_ERROR и обработать соответствующим образом. Пример работы с ошибками, возникающими в ходе работы с классами архивирования, представлен ниже в виде скрипта:

4.5. Описание файлов, приложенных к статье

Ниже приведено краткое описание файлов, приложенных к статье:

  • Zip\Zip.mqh — содержит основной класс для работы с архивами CZip.
  • Zip\ZipContent.mqh — содержит базовый класс CZipContent для основных классов элементов архива: CZipFile и CZipDirectory.
  • Zip\ZipFile.mqh — содержит класс для работы с ZIP-файлами архива.
  • Zip\ZipDirectory.mqh — содержит класс для работы с ZIP-папками архива.
  • Zip\ZipHeader.mqh — в файле даны описания структур File Local Header, Central Directory и End Central Directory Record.
  • Zip\ZipDefines.mqh — перечислены определения, константы и коды ошибок, используемые при работе с классами по архивированию.
  • Dictionary.mqh — вспомогательный класс, обеспечивающий контроль уникальности имен файлов и директорий, добавляемых в архив. Алгоритм работы этого класса подробно описан в статье «Рецепты MQL5 — Реализуем ассоциативный массив или словарь для быстрого доступа к данным».

Все файлы, приведенные в статье, необходимо разместить относительно внутреннего каталога \MQL5\Include. Для начала работы с классом в проект необходимо включить файл Zip\Zip.mqh. Опишем в качестве примера скрипт, создающий ZIP-архив и записывающий в него текстовый файл с сообщением «test»:

После его выполнения на жестком диске компьютера в центральном каталоге файлов для MetaTrader 5 появится новый ZIP-архив с именем Test.zip, содержащий один текстовой файл с надписью «test».

Архив, прилагаемый к данной статье, создан с помощью MQL-архиватора CZip, который здесь описан.

Заключение

Мы подробно рассмотрели структуру ZIP-архива и создали классы, реализующие работу с этим типом архивов. Этот формат архивирования был разработан еще в конце 80-ых годов прошлого века, но это не мешает ему оставаться самым популярным форматом сжатия данных. Набор данных классов может оказать разработчику торговых систем неоценимую пользу. С его помощью можно экономно хранить собираемые данные, будь то тиковая история или другая торговая информация. Часто различная аналитическая информация также предоставляется в сжатом виде. В этом случае умение работать с такой информацией даже в сжатом виде также может оказаться полезным.

Описываемые классы скрывают многие технические аспекты работы с архивами, предоставляя на пользовательском уровне простые и понятные методы работы с ними, сходные с теми операциями, что привыкли совершать пользователи с программами архивирования: добавление и извлечение файлов из архива, создание новых и загрузка уже существующих архивов, в том числе размещенных на удаленных сторонних серверах. Эти возможности полностью решают большинство задач, связанных с архивированием, и делают программирование в среде MetaTrader еще проще и функциональнее.

Как установить на файл атрибут только для чтения?

Всем привет Значит поговорим мы сегодня о том, как поставить атрибут на файл только чтение, то есть чтобы файл можно было только прочитать. Ничего записывать в него не получится, если стоит такой атрибут.

Значит для чего вообще эта штука может понадобится? Честно говоря я не знаю где это может быть нужно, но вот например файл hosts (это системный важный файл, находится тут: %SystemRoot%\system32\drivers\etc) имеет атрибут только для чтения и это сделано в целях безопасности, чтобы в этот файл ничего нельзя было записать. Хотя я не уверен насколько это сильная защита. В общем еще раз, если поставить атрибут только для чтения, то файл можно будет ТОЛЬКО считать с диска, записать в него ничего уже не получится. Ну, надеюсь что все понятно

На системном диске C:\ я создал для теста пустой текстовый файл test.txt, сейчас я покажу как поставить этому файлу атрибут только для чтения. Итак, смотрите, вот сам файл:

Теперь нужно зайти в его свойства, для этого нажимаете правой кнопкой по нему и там выбираете в менюхе последний пункт Свойства:

Потом появится окошко Свойства, вот в этом окошке вам нужно поставить галочку на только чтение:

Все, потом нажимаете ОК и все, у вас файл уже будет только для чтения. Ну что, сложно? Вот и я думаю что нет! Теперь смотрите, вот я его открыл и написал там слово:

Теперь я его закрываю, то есть нажимаю на крестик, появляется такое сообщение:

Ну, я тут нажал кнопку Сохранить… И вот ребята, из-за того что стоит атрибут только для чтения, то у меня выскочило такое окошко:

Это чтобы сохранить изменения. Но сохранить можно только в другом файле, ведь в свойствах test.txt стоит атрибут только для чтения, понимаете что это за прикол? Но самое интересное, что если я в этом окошке выберу файл test.txt, и нажму кнопку Сохранить, ну чтобы его перезаписать, то у меня сперва появилось такое сообщение:

Ну я там нажал Да, но потом все равно мне было сказано, что ничего не получится у меня, ибо этот файл доступен только для чтения, вот смотрите, вот это сообщение:

Ну то есть я думаю что вам все понятно, да? Если стоит атрибут только для чтения, то в файл реально ничего нельзя записать, все работает

Но можно задать атрибут и очень крутым способом, это при помощи командной строки! Я об этом напишу сейчас, вдруг вам пригодится то, а? Ну а вдруг? В общем смотрите, сначала вызываем командную строку, то есть зажимаем кнопки Win + R и пишем в окошке Выполнить такую команду:

Потом нажали ОК, после чего появится вот такое черное окно, это и есть командная строка:

А вот и команда, которая нужна чтобы задать атрибут:

Чтобы узнать как она работает, то в командной строе нужно так набрать:

Потом нажать энтер и у вас будет такой результат:

Немного непонятно? Понимаю, вот поэтому пишу, что для того чтобы через командную строку установить атрибут для файла только чтение, то нужно написать вот такую команду:

ATTRIB +R C:\test.txt

Я вот тоже сейчас попробую задать атрибут через командную строку, вот я вставил команду:

Нажал потом энтер и вот результат:

То есть результата то и по сути нету! Думаете ошибка? Нет ребята, это не ошибка, это как раз таки ее отсутствие, а значит все прошло нормалек. Я потом проверил, таки да, атрибут только чтение установился. Вы мне скажите, йолки палки, да ведь ты его уже выше поставил вручную! Нет ребята, я перед тем как поставить его через командную строку, то я пошел в свойства и снял галочку! Так что тут все четко

Теперь, основываясь на этой команде, можно сделать и другие. Ну вот например буква R это атрибут для чтения, верно? Ну вот, а буква A это атрибут архивный, буква S это системный, буква H это скрытый, буква I задает атрибут неиндексированное содержимое, ну то есть чтобы этот файл не индексировался там где-то, короче это типа для того чтобы поиск был быстрый и все такое, думаю вы поняли. Ну и ключи там еще есть всякие как видите. Но как пользоваться ключами и вообще как например задать атрибут сразу нескольким файлам? Тут тоже все просто! Я создал папку test, в ней есть файл test.txt и еще одна папка test, в которой тоже есть файл test.txt, ну вот так я сделал, но зачем? Это ребятки для примера, теперь как сделать так, чтобы в папке test все что внутри имело атрибут… ну пусть будет скрытый. Как? Очень просто, нужно написать в командную строку вот эту команду:

ATTRIB +H C:\test\*.* /S /D

Вот такая вот команда ребята! Я только что проверил, все работает, это правильная команда. В итоге у меня в папке test было все пусто, потому что все файлы и папки были скрыты, а у меня отключен показ скрытых файлов и папок. Но давайте немного разберемся с командой, что я там написал? Буква H (наверно от слова Hidden) указывает, что нужно задавать атрибут скрытый. Потом идет путь к папке, а в конце пути идет такое:

Вы наверно подумаете, что за дичь? А это означает что в папке нужно обрабатывать все файлы, которые имеют название * и расширение *, но сами эти звездочки, то они означают как бы любое значение. Вообще эти звездочки это называется типа маска, ну есть такое. Дальше идет такое как /S, это означает что обрабатывать нужно все файлы с указанным именем, а так как мы указали *.*, то обработаны будут все файлы. Ну и чтобы еще были обработаны папки, то для этого я добавил ключ /D, ну что ребята, все понятно или я тут немного запутано все написал? Ну, надеюсь что все таки вам тут все понятно!

Ой, еще самое главное забыл вам написать, вы в команде видите плюсик? Ну так вот, тот плюсик, это чтобы УСТАНОВИТЬ атрибут! А чтобы СНЯТЬ атрибут то нужно ставить МИНУС! Вот блина, как я мог забыть и не написать об этом? Капец!

Ребята, на этом все. Опять же скажу, что надеюсь что все вам тут было понятно, ну а если что-то не так, ну то уж извините, что я могу поделать, я видимо как-то странно обьясняю.. Удачи вам в жизни и чтобы у вас всегда было отличное настроение

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Илон Маск рекомендует:  Что такое код poly
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL