Название: 4.4.0: Utf-8 и QTextStream::seek() Отправлено: Racheengel от Декабрь 01, 2008, 10:58 Всем привет :)
Запостил сюда, ибо не знаю, куда лучше по теме. В общем есть такая задача: текстовый файл в кодировке Utf-8 (очень большой), который необходимо индексировать (пробежаться по нему однажды, найти некоторые маркеры и выгрузить в индексный файл их позиции). Использую такой вариант: Код: QFile f(...); Проблема в том, что последующее чтение с помощью QTextStream::seek(index) позиционирует указатель на неверный индекс, а именно - QTextStream::seek() игнорирует установленный кодек и устанавливает смещение в байтах, а не в символах (как это должно быть по хорошему). В принципе, я считаю это багом и намерен зарепортить тролям, ибо read(size) работает как надо в отличие от seek() (т.е. читает size символов, а не байтов). Знает ли кто адекватное решение? Мне в голову приходит только чтение в виде QByteArray и последующий поиск маркеров побайтно, но поскольку кроме этого необходимо произвести еще кое-какие операции со строками, код выростет раза в два (и производительность грохнется в столько же). Название: Re: 4.4.0: Utf-8 и QTextStream::seek() Отправлено: Alex03 от Декабрь 01, 2008, 16:10 Как Вы представляете seek() в символах?
Только через чтение файла с самого начала.... А это накладно и теряется всякий смысл в индексации. Я никакого бага тут не вижу, тем более что весь файл не обязан быть текстровым. Ну а как предложение - при индексации сохранять смещения в файле в байтах а не в символах. Название: Re: 4.4.0: Utf-8 и QTextStream::seek() Отправлено: Racheengel от Декабрь 01, 2008, 16:40 Ну, собственно, QTextStream-то ориентирован как раз на текстовые файлы, иначе я бы юзал QDataStream.
В принципе, теоретически можно реализовать враппер для посимвольного поиска, но... это геморойно, да... Наверное все-таки буду читать поток побайтово. Но все же это не очень удобно - работать с текстовым файлом как с бинарным только потому, что Utf-8 довольно дурацкая кодировка в плане того, что некоторые символы представлены 1, а некоторые 2 байтами - будь моя воля, юзал бы Utf-16, но... такие исходные файлы, ничего не поделать... Название: Re: 4.4.0: Utf-8 и QTextStream::seek() Отправлено: Tonal от Декабрь 03, 2008, 09:41 Ежели маркеры всегда в пределах одной строки, то алгоритм такой:
Код Здесь find_mark принимает очередную строку и возвращает нужные данные о маркере или False если ничего не нашла. save_mark - принимает позицию старта строки, саму строку и данные о маркере, которые вернула find_mark. Скорость будет весьма неплохой. Памяти потребуется немного. Пример ишет первое вхождение любой подстроки из eni, beni, riki, taki в строке файла данных и выводит на стандартный вывод позицию строки, позицию найденной подстроки и её саму: Код Переложить на С++ труда не составляет. Если маркеры могут захватывать несколько строк - придётся несколько усложнить create_mark_index организуя окно. Если реализовать нормально (кольцевой буфер, например), на скорость это мало повлияет. :) Название: Re: 4.4.0: Utf-8 и QTextStream::seek() Отправлено: Racheengel от Декабрь 03, 2008, 12:04 В принципе, я реализовал все с QByteArray.
Мне маркеры надо искать по всему файлу, так что я читаю все сразу в память и ищу через indexOf(). Получаю бинарный индекс, который потом отлично работает с seek(). Ну а когда надо прочитать собственно текст по маркеру, делаю seek(), потом выставляю кодек в Utf-8 и читаю уже как строку. Все работает как надо. Спасибо всем за советы :) |