ReadLn, работающий с WideString (файлы utf-8) - PullRequest
3 голосов
/ 08 января 2011

Я использую Delphi 7.

Мне нужно построчно читать файл utf-8, каждая строка содержит слово и его вес (число). Поэтому мне нужно прочитать каждую следующую строку, а затем разделитьстрока с разделителем (tab char) и сохраните это в памяти.

Итак,

1) есть библиотека для работы с файлами utf-8 в Delphi (возможно, третья сторона)

2) будут ли функции работать нормально с самой широкой строкой?Я использую PosEx.Так что, если нет, можете ли вы дать ссылку на стороннюю библиотеку для работы с широкими строками?

Ответы [ 5 ]

4 голосов
/ 08 января 2011

Если вы действительно имеете дело с UTF-8, то вам не нужно ничего особенного, если только вы читаете и обрабатываете его. Вы должны иметь возможность рассматривать их как pchar или даже как обычную строку Delphi 7. Если вы попытаетесь отобразить содержимое в каком-либо окне сообщения, вам может потребоваться выполнить некоторые преобразования. Например, я не верю, что метод окна сообщений Delphi 7 будет правильно отображать строки UTF-8, если строка содержит байтовые значения более 127 (0x7f). Для чего-то подобного вам нужно будет преобразовать в UTF-16 и вызвать Windows API MessageBoxW или что-то подобное. В противном случае, однако, строки UTF-8 могут обрабатываться во многих ситуациях так же, как строки ANSI с одним байтом.

Я не думаю, что UTF-8 обычно называют "широкоформатной". Я могу ошибаться, но я думаю, что это обычно означает UTF-16.

2 голосов
/ 08 января 2011

Если ваш файл закодирован как UTF-8, а символы, которые вы ищете, являются ASCII, тогда вообще не нужно использовать WideString.ASCII является подмножеством UTF-8, и любой символ ASCII гарантированно не будет мешать специальной кодировке, используемой для других символов в UTF-8.Цифровые символы от 0 до 9 и символы табуляции - все ASCII.

JCL поставляется с различными функциями и классами для работы с Unicode, если вам действительно нужноиспользуйте их.

1 голос
/ 08 января 2011

Если большая часть вашего ввода - UTF-8, может стоило бы изменить вашу кодовую страницу при запуске с "default" на utf8 (кодовая страница 65001).Это приведет к тому, что все преобразования с краткой строкой фактически превратятся в без потерь utf-8-> utf-16.

В D7 вам понадобится набор так называемых «юникодных» компонентов, которые основаны наWinapi -W функции.Собственные компоненты Delphi делают это только с выпуском D2009, который переключает тип строки по умолчанию на UTF-16.

Если вы хотите вложить значительные средства в поддержку Unicode, обновление может быть разумным занятием

1 голос
/ 08 января 2011

WideString - это реализация UTF-16 (совместимая с COM BSTR), она не может хранить строки UTF-8, если вы назначите 8-битную строку, она будет преобразована в UTF-16. Но если вы явно не используете правильную функцию преобразования, Delphi будет интерпретировать 8-битную строку, используя текущую кодовую страницу.

Строка UTF-8 может храниться в Delphi AnsiString (тип строки по умолчанию в Delphi 7), но функции управления строками предназначены для кодовых страниц ANSI, а не UTF-8. Разница в том, что UTF-8 является многобайтовым набором символов. Но первые 127 символов ANSI, для кодирования данного «символа» требуется более одного байта, в то время как для многих кодовых страниц ANSI (особенно для европейских языков) требуется только один байт, кодируя только 255 «символов» (тогда как UTF-8 может кодировать весь набор Unicode).

Если вы просто ищете символ табуляции AFAIK, вы можете просто использовать AnsiString, но вы должны убедиться, что любой байт выше $ 80, который вам может понадобиться, не является частью многобайтовой последовательности. Если у вас есть более сложные потребности обработки, может быть проще найти библиотеки, работающие со строками UTF-16, чем UTF-8. Как сказал Роб Кеннеди, JCL является хорошей отправной точкой в ​​качестве бесплатной библиотеки, реализующей UTF-манипуляции со строками.

0 голосов
/ 09 января 2011

Вы можете просто прочитать файл как есть в обычный TStringList через его методы LoadFrom ... (), а затем перебрать список по мере необходимости.Если загрузка всего файла в память за один раз невозможна, вы можете открыть файл с помощью TFileStream, а затем использовать метод TStreamReader.ReadLine () для построчного чтения потока.

Если вам нужно декодировать заданную последовательность UTF-8 в UTF-16 для обработки, я бы предложил использовать функцию MultiByteToWideChar () Win32 API напрямую, только потому, что функция RTL UTF8Decode () имеет сломанную реализацию UTF-8 в более ранней версии Delphi.версии (не уверен в D7, но он определенно работает в D6).

Хорошая особенность любого подхода к загрузке состоит в том, что они оба поддерживают кодирование в D2009 и более поздних версиях, что означает, что если вы когда-либо обновитесь, выможет сделать несколько очень небольших изменений кода, чтобы сообщить RTL, что данные представляют собой UTF-8, и он автоматически декодирует их в UTF-16, а затем остальная часть вашего кода обработки может остаться прежней (при условии, что выне делать ничего, что связано с Анси).

...