ReadLn работает с WideString (файлы utf-8)

Я использую делфи 7.

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

So,

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

2) будут ли функции нормально работать с широкими строками? Я использую ПосЭкс. Итак, если они этого не сделают, можете ли вы также дать ссылку на стороннюю библиотеку для работы с широкими строками?


person EugeneP    schedule 07.01.2011    source источник


Ответы (5)


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

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

person Mark Wilkins    schedule 07.01.2011

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

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

person Rob Kennedy    schedule 07.01.2011

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

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

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

person Marco van de Voort    schedule 08.01.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.

person Community    schedule 07.01.2011

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

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

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

person Remy Lebeau    schedule 09.01.2011