Опубликован: 02.08.2013 | Уровень: для всех | Доступ: платный
Самостоятельная работа 7:

Работа с JSON, XML, сжатие данных

< Лекция 18 || Самостоятельная работа 7: 123 || Самостоятельная работа 8 >

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

Рассмотрим код метода cmd_SerializationXML_Click, обработчика события нажатия на кнопку "Сериализация, XML".

Здесь мы сначала создаём объект типа ForSerialization. После создания в конструкторе производится его инициализация, он готов к дальнейшим исследованиям.

В переменную типа Type запишем тип данных объекта – эта переменная понадобится нам при настройке сериализатора. Конечно, необязательно создавать отдельную переменную, тип объекта для сериализации можно получить и в конструкторе сериализатора. Сериализатор – объект типа XmlSerizlizer, создаётся с указанием типа данных, которые мы собираемся сериализовать.

Следующим шагом является создание потока, в данном случае это поток типа MemoryStream, в который мы собираемся записывать сериализованные данные. В качестве потоков могут выступать и другие потоки. Например, те, которые соответствуют открытым файлам.

Метод Serialize объекта типа XmlSerizlizer, выполняет сериализацию. При его вызове указывается, во-первых, поток, в который нужно записать сериализованные данные, во-вторых – объект, который следует сериализовать. После выполнения сериализации наш поток содержит XML-представление объекта, мы можем, при практическом использовании данного механизма, отправить это представление по сети, сохранить на диск. Сейчас мы хотим получить строковое представление потока для того, чтобы просмотреть его. Для этого мы сначала устанавливаем указатель потока на его первую позицию, затем создаём объект типа StreamReader, с помощью которого можно прочитать поток. Мы будем читать его в строку XmlString и выводить на экран в виде сообщения, которое можно прочитать. Это сообщение будет содержать следующий текст:

<?xml version="1.0" encoding="utf-8" ?> 
- <ForSerialization xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
<Line1>Пример строки</Line1> 
<Number1>123</Number1> 
- <IntArray> 
<int>-518451200</int> 
<int>-463632356</int> 
<int>1312024067</int> 
<int>689675499</int> 
<int>-43902912</int> 
<int>-202627666</int> 
<int>-1059162278</int> 
<int>-489792147</int> 
<int>971228309</int> 
<int>1326244365</int> 
</IntArray> 
</ForSerialization>

Как видно, здесь содержатся данные об объекте ForSerialization, которые позволят восстановить его, то есть – десериализовать. После вывода сообщения, имея поток, который содержит сериализованные данные, мы создаём десериализатор. Это – так же объект XmlSerizlizer, при его создании указывается тип данных, с которыми мы хотим работать. При создании объекта на основе сериализованных данных, мы вызываем метод Deserialize объекта XmlSerializer, приводя полученный объект к нужному типу. Для того, чтобы проконтролировать правильность создания объекта, можно установить точку останова на строку, которая выводит сообщение об успешной десериализации и просмотреть в отладчике полученный объект, сравнив его с исходным объектом, который мы сериализовали.

В обработчике события нажатия на кнопку "Сериализация, JSON", мы выполняем ту же последовательность действий, которую выполняли для XML, но – для формата JSON. Для сериализации используем объект типа DataContractJsonSerizlizer, при его создании так же нужно указать тип объекта, который мы собираемся сериализовать. Подготовим поток в памяти, который примет сериализованные данные и, командой WriteObject, сериализуем объект. Дальнейшие действия схожи с вышеописанным для XML, мы получаем из потока строку и выводим в сообщении. Вот как выглядит это сообщение, содержащее данные объекта, сериализованного в JSON:

{"IntArray":[1394960975,-1568024929,-1589055262,1970233772,-819919232,
-1407633318,125844691,1787338925,-643262746,-232092512],
"Line1":"Пример строки","Number1":123}

На примере данных, полученных в результате сериализации объектов с использованием форматов JSON и XML хорошо видна разница между ними, о которой мы упоминали выше. А именно, при представлении данных в формате JSON для их хранения и передачи потребуется меньше ресурсов (для более сложных объектов эта разница еще существеннее), чем при использовании XML. В то же время, XML-код легче воспринимать. Опять же, особенно хорошо это заметно при работе с более крупными объектами. При передаче данных по сети, в ходе взаимодействия с каким-либо сервисом, использование JSON, при прочих равных условиях, даст более высокую скорость обмена данными, приведет к экономии сетевого трафика. Если подсчитать количество символов, которое занимают XML и JSON-код (нас интересуют скорее не сами цифры, так как мы не учитываем здесь кодировку, в которой будут сохранены эти данные, не учитываем возможность их сжатия, а соотношение), то окажется, что JSON-представление данных занимает 164 символа, XML-представление – 474. То есть, XML-данные, содержащие тот же объем полезной информации, в нашем случае, примерно в 2,8 раза больше.

Продолжая пример работы с JSON, мы, используя уже имеющийся поток, хранящий сериализованные данные, десериализуем их, создавая на их основе новый объект, пользуясь методом ReadObject объекта типа DataContractJsonSeriаlizer.

Принимая решение об использовании того или иного способа сериализации данных и работы с такими данными (например, в XML или JSON могут поступать ответы веб-службы на посылаемые ей запросы), следует рассмотреть возможность использования альтернативных библиотек, реализующих эти возможности. Сериализация и десериализация способна создать некоторую нагрузку на систему (а при работе с большими объемами данных, получаемыми, например, от веб-службы – нагрузку довольно ощутимую), поэтому оптимизации этого процесса стоит уделить внимание. Ответ на вопрос о целесообразности использования того или иного формата не так очевиден, как может показаться на первый взгляд. Дело в том, что работа с XML-данными и JSON-данными требует различных вычислительных ресурсов. Скорость её выполнения зависит от данных, с которыми осуществляется работа, от используемых библиотек для сериализации и десериализации, от других факторов. Всё это говорит в пользу проведения предварительных испытаний каждой из этих технологий при работе с конкретной службой (возможно, конечно, что выбор будет сделан в пользу какой-нибудь другой технологии передачи и хранения данных) и сравнения результатов таких испытаний.

Обработчик нажатия на кнопку Сжатие данных демонстрирует работу с библиотекой Zlib, в частности, её методы CompressString и UncompressString. Мы используем здесь строковую переменную, которая содержит некоторый текст. Мы можем передать эту строку методу CompressString, но он возвращает результаты сжатия в байтовый массив (эта библиотека поддерживает и работу с потоками). Этот байтовый массив мы передаем методу UncompressString – он возвращает данные в строку. Предварительно, для оценки уровня сжатия, который был достигнут при работе с нашими данными, мы записываем исходную строку в байтовый массив BytesFromString, для того, чтобы показать размер этого массива и сравнить его с массивом, хранящий сжатое представление данных. В нашем случае массив, хранящий исходную строку, содержит 104 байта, массив, хранящий те же данные в сжатом виде – 64 байта.

Выводы

Работа с JSON, XML и другими форматами данных требуется как при создании приложений, рассчитанных на локальное использование, так и при создании сетевых приложений, обрабатывающих ответы служб, получаемые в различных форматах. Правильный выбор формата передачи данных позволяет создать приложение, которое более эффективно использует системные ресурсы. Сжатие данных – это очень важная технология, которая позволяет экономить место – как на устройствах хранения данных, так и при передаче данных по сети. Однако, её использование подразумевает некоторые затраты вычислительных ресурсов. Всё это говорит в пользу тщательного подхода к выбору технологий, которые будут применяться для создания того или иного приложения.

Задание

Подумайте, как ваше приложение может воспользоваться возможностями сериализации и десериализации в организации его работы. Оцените возможную выгоду от использования возможностей сжатия данных при организации хранения данных вашего приложения. На основе примера, приведенного в лабораторной работе, создайте приложение, которое позволяет оценить скорость сериализации объекта, объем данных которого можно регулировать в диапазоне 10 – 50 Мб, и десериализации данных в такой объект. Используйте в эксперименте форматы JSON и XML Для оценки времени можно воспользоваться возможностями получения текущего времени в начале и в конце операции. Подготовьте отчет о проведенной работе.

Дополнительные материалы

К данной лекции подготовлено видеоприложение и демонстрационный программный проект.

< Лекция 18 || Самостоятельная работа 7: 123 || Самостоятельная работа 8 >
Вася Пупкин
Вася Пупкин
Россия, с. Оймякон
антон Антонкин
антон Антонкин
Россия