QT 4: программирование GUI на С++
Шрифт:
Обеспечение в пользовательских типах данных операторов ввода—вывода в поток дает несколько преимуществ. Одно из них заключается в том, что это позволяет нам выводить в поток контейнеры с пользовательскими типами. Например:
Мы можем так же просто считывать контейнеры:
Это
При использовании QDataStream Qt обеспечивает чтение и запись каждого типа, включая контейнеры с произвольным числом элементов. Это освобождает нас от структурирования того, что мы записываем, и от выполнения какого бы то ни было синтаксического анализа того, что мы считываем. Необходимо лишь гарантировать чтение всех типов в той же последовательности, в какой они были записаны, предоставляя Qt обработку всех деталей.
QDataStream имеет смысл использовать как для своих собственных пользовательских форматов файлов, так и для стандартных двоичных форматов. Мы можем считывать и записывать стандартные форматы двоичных данных, используя потоковые операторы для базовых типов (например, quint16 или float) или при помощи функций readRawBytes и writeRawBytes. Если QDataStream используется только для чтения и записи «чистых» типов данных С++, нет необходимости вызывать функцию setVersion.
До сих пор мы загружали и сохраняли данные, жестко задавая в программе версию потока QDataStream::Qt_4_1. Этот подход прост, и он надежно работает, но он имеет один небольшой недостаток: мы не сможем воспользоваться новыми форматами и обновленными версиями форматов. Например, если в более поздней версии Qt добавится новый атрибут к QFont (кроме размера точки, наименования шрифта и так далее) и мы жестко закодируем номер версии Qt_4_1, этот атрибут не будет сохраняться и загружаться. Существует два решения. Первое решение заключается во включении номера версии QDataStream в файл:
(MagicNumber — это константа, которая уникально идентифицирует тип файла.) В этом случае мы всегда будем записывать данные с применением последней версии QDataStream (каким бы результат ни был). При считывании файла мы считываем номер версии потока:
Мы
Если файл использует формат с собственным номером версии, мы можем его использовать для определения номера версии потока, а не хранить этот номер в явном виде. Предположим, что файл сформирован в формате версии 1.3 нашего приложения. Тогда мы могли бы записать данные следующим образом:
При считывании данных мы определяем версию QDataStream на основе номера версии приложения:
В этом примере мы говорим, что для любого файла, сохраненного в приложении с версией меньшей, чем 1.3, используется версия 4 потока данных (Qt_3_0), а для файлов, сохраненных в приложении с версией 1.3, используется версия 7 потока данных (Qt_4_1).
Итак, существует три политики работы с версиями потоков данных QDataStream: жесткое кодирование номера версии, запись и чтение номера версии в явном виде и использование различных жестко закодированных номеров версий в зависимости от версии приложения. Можно применять любую из этих политик для гарантирования чтения данных новой версией приложения, записанных в старой версии, даже если сборка новой версии приложения выполняется с более свежей версией Qt. После выбора политики обработки версий QDataStream чтение и запись двоичных данных в Qt становятся простыми и надежными.