Russian Qt Forum
Март 29, 2024, 10:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Смена QTextCodec на лету  (Прочитано 1899 раз)
DarkHobbit
Самовар
**
Offline Offline

Сообщений: 189


Просмотр профиля
« : Декабрь 27, 2021, 23:49 »

Добрый день.

Мне приходится обрабатывать текстовый файл, в котором смешаны разные кодировки (частично UTF-8, частично ANSI - для русского языка это cp1251). Как ни странно, это MPB - файл резервной копии достаточно известной и пользующейся уважением программы MyPhoneExplorer, пожалуй, лучшего решения для извлечения и восстановления контактов, сообщений, истории вызовов и кое-чего ещё с андроид-телефонов на ПК. Почему немецкий автор сделал такой странный контейнер, я не знаю, но формат есть и довольно популярный. Соответственно я в 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). Но это вопрос отдельный, мне бы с тем, что есть, разобраться...
Записан

Мои проекты на Qt: DoubleContact, LInvert
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Декабрь 28, 2021, 16:47 »

Кмк, предупреждение касается и файлов. Наверняка они читаются кусками фиксированной длинны. А QFile и QAbstractSocket наследуются от QIODevice

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

Если же нужна эффективность, то я бы смотрел в сторону создания своей обёртки над QIODevice, которая бы проксировала данные из файла
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.05 секунд. Запросов: 22.