Russian Qt Forum

Qt => Общие вопросы => Тема начата: DarkHobbit от Декабрь 27, 2021, 23:49



Название: Смена QTextCodec на лету
Отправлено: DarkHobbit от Декабрь 27, 2021, 23:49
Добрый день.

Мне приходится обрабатывать текстовый файл, в котором смешаны разные кодировки (частично UTF-8, частично ANSI - для русского языка это cp1251). Как ни странно, это MPB - файл резервной копии достаточно известной и пользующейся уважением программы MyPhoneExplorer (http://"https://www.fjsoft.at/en/"), пожалуй, лучшего решения для извлечения и восстановления контактов, сообщений, истории вызовов и кое-чего ещё с андроид-телефонов на ПК. Почему немецкий автор сделал такой странный контейнер, я не знаю, но формат есть и довольно популярный. Соответственно я в DoubleContact его поддерживаю.

Я использовал QTextStream::setCodec(), вызывая его прямо посреди файла, при переходе к следующей секции. На очень старых Qt - <4.8 - при этом сбивалась позиция в файле (подозреваю, из-за несовпадения длины символов в разных кодировках). В Qt 4.8.* и Qt5 вроде бы проблема решилась, но сейчас, когда я стал читать большинство секций файла MPB, а не только некоторые, опять начались артефакты.

Вопрос, собственно, в следующем. Насколько "законно" вызывать QTextStream::setCodec() посреди чтения файла? В документации я нашёл только такую оговорку:

Цитировать
Warning: If you call this function while the text stream is reading from an open sequential socket, the internal buffer may still contain text decoded using the old codec.

Но это, как я понимаю, только про сетевые сокеты?

Или в этом случае надёжнее вообще отказаться от QTextStream и читать весь файл как набор байтов, а потом уже разные секции перекодировать разными кодеками из QByteArray в QString? Тогда и от readLine придётся отказаться и ловить границы строк самому...

P.S. Я в курсе, что в Qt6 начали крестовый поход против QTextCodec и замену его "обезжиренными" классами, работающими только с юникодом. Довольно странная позиция, учитывая. что из реальной жизни неюникодные кодировки никуда не ушли и не уйдут ещё скоро. Именно поэтому поддерживать Qt6 я пока не тороплюсь, в глубине души теплится надежда, что корпоративные клиенты их образумят (а не образумят - придётся тащить в свои проекты libiconv). Но это вопрос отдельный, мне бы с тем, что есть, разобраться...


Название: Re: Смена QTextCodec на лету
Отправлено: __Heaven__ от Декабрь 28, 2021, 16:47
Кмк, предупреждение касается и файлов. Наверняка они читаются кусками фиксированной длинны. А QFile и QAbstractSocket наследуются от QIODevice

Я бы смотрел в сторону того плана, что вы описали - нарезать на куски и по отдельности прочитать. Вроде это проще всего

Если же нужна эффективность, то я бы смотрел в сторону создания своей обёртки над QIODevice, которая бы проксировала данные из файла