четверг, 24 сентября 2009 г.

Хранение бинарных данных

В этой статье речь пойдёт о вставке бинарных данных прямо в файл программы EXE. Бинарные данные - это картинки, звуки, видео и вообще любые файлы. Даже текстовые файлы можно вставить в программы HiAsm как бинарные данные.
В Delphi для вставки двоичных (бинарных) данных требуется создавать файлы ресурсов, прописывать их в коде программы, а в HiAsm всё гораздо проще. Все утомительные процедуры скрыты, и их не приходится выполнять самостоятельно.

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

Начнём вставку двоичных данных с картинок. Именно с картинок, а не с картинки, потому что для разных форматов картинок - разные компоненты. Ведь форматы - это не просто расширения, это ещё и алгоритмы упаковки/распаковки картинок.

Все нужные компоненты находятся на вкладке "Графика", в группе "Картинка". Значки компонентов даже подписаны: bmp, jpg, png, ico.



Формат BMP - самый простой графический формат, в файлах которого каждый пиксель описывается определённым числом байт. Обычно тремя. Перед отображением любой картинки на форме картинка сначала должна быть представлена как набор пикселей, поэтому любой графический файл сначала перекодируется в bmp. По этой причине в компонент Bitmap можно вставлять картинки любых форматов, они все будут переведены в bmp и сохранены соответственно (картинка находится в параметре Picture).

Формат JPEG является уже сжатым форматом, перед отображением которого нужно перекодирование. В компонент Jpeg уже можно вставить только картинки формата jpg. И сохранены в файле проекта они будут именно как jpg, а не bmp.

Иконки (компонент Icon) тоже сохраняются как иконки, а не bmp.

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

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

Теперь отобразим на форме картинку. Сами компоненты, про которые шла речь, невизуальные и отображать ничего не могут, а могут только сохранять и ещё преобразовывать. Отображением занимается компонент Image со вкладки "Интерфейс". В редакторе форм он отлично отображается. В него, кстати, тоже можно вставить картинку любого формата, как и в компонент Bitmap. В некоторых случаях это удобно, но иногда нужно сразу не показывать картинку, а загрузить её потом.



Здесь при нажатии кнопки появляется картинка. Она загружается через верхнюю точку, из компонента Bitmap.

Но картинку jpg так просто не загрузить, ведь она же закодированная. Но компонент Jpeg может перекодировать картинку из jpg в bmp и обратно, если нужно. А это бывает нужно, если вы что-то нарисовали, например, и хотите сохранить это в формате jpg в файл.



Метод doBitmap компонента Jpeg взят со вкладки "Точки" панели параметров и как раз перекодируется jpg в bmp. При этом jpg-картинка берётся из самого компонента.

Аналогичным способом можно работать и с другими картинками.


Перейдём теперь к звуковым данным. На вкладке "Мультимедиа" есть компонент PlaySound, он второй. У него есть параметр Sound, в который можно загрузить звук (только wav!), и он сохранится в программе, а проигрывать его можно через метод doPlay. Как видите, для проигрывания звука не нужен отдельный компонент.


Сохранение в программе конкретных типов данных мы рассмотрели, а теперь перейдём ко вставке любых типов данных. Есть в hiasm на вкладке "Файлы", в группе "Потоки" компонент MemoryStream. В нём можно сохранять любые двоичные данные (т.е. файлы).



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

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



Выделите компонент FileStream. Параметр Mode у него указан Write. Это значит, что файл, указанный в параметре FileName, мы используем для записи, а не для чтения. И если указанного файла не существует, то он будет создан.

Также есть параметр AutoCopy, который установлен в True. Это значит, что файл будет открываться и закрываться после записи автоматически при испльзовании метода doCopyFromStream. На этот метод нужно подать файловый поток (т.е. те самые бинарные данные), что мы и сделали через компонент DoData. При нажатии кнопки двоичные данные сохранятся в файл "Проба.rar". Ну а поскольку загружен в компонент MemoryStream изначально был как раз архив rar, то файл прекрасно откроется, и ы увидите там пустой файл Excel.

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

6 комментариев:

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

    ОтветитьУдалить
  2. Для рекламы как раз не нужно создавать где-то файл. Она может показываться в программе (картинкой).
    Троян незамеченным тоже вряд ли здесь пройдёт, поскольку осуществляется запись на диск, где её сразу проверяет антивирус. Другое дело, если троян запускается из памяти программы, без копирования на диск...Но делать подобные вещи никто не будет (в смысле, это невозможно через компоненты hiasm), и на форуме такие компоненты не делают, даже несмотря на их возможную пользу.

    ОтветитьУдалить
  3. А базу данных sqlite можно туда поместить? при этом должны сохраниться функции чтение/запись! :)

    ОтветитьУдалить
  4. Поместить-то можно, но читать и тем более записывать стандартными средствами будет нельзя. Придётся сохраняться базу из exe-шника на диск и там уже читать/записывать, а потом снова записывать её в exe-файл. Только сам в себя запущенный файл, скорее всего, записать ничего не сможет.

    ОтветитьУдалить
  5. Доброго времени суток. Хочу вставить в программу, ну допустим *.doc, с возможностью его редактирования в программе, а не открытии его в Word'e. Скажите, возможно ли это?

    ОтветитьУдалить
    Ответы
    1. Скорее всего, нет. На всякий случай - спросите на форуме hiasm.com.

      Удалить