Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Чтение данных из файла UTF-8 [D6, WinXP]


Страницы:   1 2

leonidus ©   (2008-06-13 11:58:00) 

Есть файл с данными в формате UTF8, мне нужно их прочесть и сконверировать в UTF16.

st_u:widestring;
f:textfile;

AssignFile(F, edit1.Text);
Reset(F);
readln(F,st_u);
st_u:= UTF8Decode(st_u);

В результате получаю st_u='', хотя при чтении из файла (readln(F,st_u)) строка содержит данные. Что же не так?


Anatoly Podgoretsky   (2008-06-14 00:31:00) [1]


> почему же, это может быть UTF8 - все что до 7F кодируется
> одним байтом.

Хотя бы из-за этого 00 00, а до него обычный ASCII
И больше никакой информации из файла не приведно, хотя и это достаточно, чтобы сказать, что это не UTF8


leonidus   (2008-06-13 23:57:00) [2]

Я пробовал и через BlockRead:

function StringToHex(const Source: String): String;
var i, Len: Integer;
begin
 Result := '';
 Len := Length(Source);
 for i := 1 to Len do
   Result := Result + IntToHex(Ord(Source[i]), 2) + ' ';
end;

var
Buf: array[1..20048] of Char;
st,idx:string;
FromF: file;

AssignFile(FromF, edit1.Text);
Reset(FromF, 1);
repeat
BlockRead(FromF, Buf, SizeOf(Buf), NumRead);

st:='';
for i:=1 to 20048 do
 st:=st+buf[i];
idx:=idx+st;

st:=StringToHex(st);
idx_hex:=idx_hex+st;
until (NumRead = 0);
CloseFile(FromF);

В результате получаю текстовую строку:
idx_hex=30 30 64 61 74 61 62 61 73 65 69 6E 66 6F 00 00 ....
из которой извлекаю слово, смещение и длину и помещаю все это в TtntStringList в такое примерно виде:

30 30 64 61 74 61 62 61 73 65 69 6E 66 6F=0|1313
30 30 64 61 74 61 62 61 73 65 73 63 72 69 70 74=1313|10413

до знака равно это закодированное слово, затем смещение и длина.
Осталось только декодировать само слово преобразовав его в читаемые символы не потеряв при этом юникода.


McSimm   (2008-06-13 23:55:00) [3]


> Это не UTF8

почему же, это может бытьUTF8 - все что до 7F кодируется одним байтом.


palva   (2008-06-13 22:52:00) [4]

То, что вы описывали в [13] не очень подходит для чтения текстовыми функциями ReadLn. Для двоичного чтения используйте функцию BlockRead, либо другой метод чтения при помощи TFileStream. Но здесь, конечно, вам надо освоиться с чтением строки или целого числа из файла при помощи двоичного чтения.


leonidus   (2008-06-13 22:30:00) [5]

ок, Анатолий тогда подскажите как прочесть эти данные и записать в WideString


Anatoly Podgoretsky   (2008-06-13 22:27:00) [6]

> leonidus  (13.06.2008 22:14:20)  [20]

Это не UTF8


leonidus   (2008-06-13 22:14:00) [7]

[18] так я же приводил:
30 30 64 61 74 61 62 61 73 65 69 6E 66 6F 00 00


palva   (2008-06-13 21:56:00) [8]


> вот файл с которым борюсь:

С файлом надо не бороться, с ним надо работать. Только сначала нужно освоить инструмент, которым работаете. Тогда это и будет кропотливая и нудная, но работа, а не борьба. Инструмент освоить здесь вам пожалуй что и помогут. А вот разбираться с файлом вряд ли будут, даже если вы будет уверять, что UTF8Decode не работает.


Anatoly Podgoretsky   (2008-06-13 21:37:00) [9]

А сюда привестм, что несколько байтов с UTF8 как просили не можешь?


leonidus   (2008-06-13 19:56:00) [10]

вот файл с которым борюсь:
http://www.realsofts.com/fr-ru-synt.zip


Anatoly Podgoretsky   (2008-06-13 19:39:00) [11]

> leonidus  (13.06.2008 19:17:14)  [14]

Попробуй сам преобразовать свои хекс коды в ANSI и сам увидишь.


palva   (2008-06-13 19:37:00) [12]

leonidus   (13.06.08 19:13) [13]
Ну то есть вопрос о неправильной работе функции UTF8Decode снят.


leonidus   (2008-06-13 19:17:00) [13]

Анатолий, мне нравится ваша лаконичность, но было бы здорово если бы она подпитывалась фактами. Я открываю файл через программу ListEdit, она определяет кодировку WIN(RUS) при этом не отображая скажем немецкие умляуты, но если я принудительно высталяю UTF-8, то все слова отображаются корректно, из чего я делаю вывод что кодировка документа именно UTF-8. что подтверждает и документация
http://stardict.sourceforge.net/StarDictFileFormatтребующая от словаря именно такой кодировки.


leonidus   (2008-06-13 19:13:00) [14]

palva дело в том что файл состоит больше чем из одного слова 00databaseinfo, а если его открывать функцией [5], то на выходе только "00databaseinfo".

А идея вот в чем я пишу конвертер словарей StarDict в свой более простой формат, по спецификации формата словарей StarDict, словарь состоит из индексного файла и файла данных. Я сейчас разбираюсь с индексным. Он в формате UTF8 (был бы UTF16 я бы без проблем открыл его средствами библиотеки TNT) содержит последовательность заголовков словарных статей , маркер конца словарной статьи это символ "00", далее идут 4 байта смещения и 4 байта длины словарной статьи, потом следующий заголовок словарной статьи и так до конца индексного файла. Следовательно первое что мне нужно, это прочесть весь индексный файл в память (я помещаю его в строку String), после чего уже работаю с ней как с массивом. Но затем мне нужно данные записать в TTntStringList после чего сохранить эту структуру на диск но для этого UTF8 нужно преобразовать в UTF16 не потеряв при этом "юникодность" т.е. словарь может содержать не только англ. и русские бурвы но и например немецкие или испанские.


Anatoly Podgoretsky   (2008-06-13 18:58:00) [15]

> leonidus  (13.06.2008 17:39:07)  [7]

Это не UTF8


palva   (2008-06-13 18:29:00) [16]


> leonidus   (13.06.08 17:39) [7]

У меня ваша строка преобразуется правильно:
Непонятно, почему у вас в результате преобразования была пустая строка. Можете попробовать следующий код:

{$APPTYPE CONSOLE}
var
 s: String;
 w: WideString;
begin
 s :='00databaseinfo'#0#0;
 w := UTF8Decode(s);
 WriteLn(Length(w));  // 16
 WriteLn(Ord(w[16])); // 0
end.

Может быть, я вас неправильно понял. Объясните точнее, что означают ваши слова в посте [3]
> так же ничего не дает.


leonidus   (2008-06-13 18:04:00) [17]

ZENsan так и не понял что нужно в вашей функции изменить, она вроде не ищет "00" для для завершения своей работы...

и можно "расшифровать" фразу "А когда нет бома, просто делай UTF8Decode и подавай строку эту." ?


ZENsan   (2008-06-13 17:45:00) [18]

измени просто функцийю если она тебе подходит немного и будет брать строку и после 00..

А когда нет бома, просто делай UTF8Decode и подавай строку эту.


ZENsan   (2008-06-13 17:43:00) [19]

У тебя UTF-8 without BOM.


leonidus   (2008-06-13 17:39:00) [20]

Это словарь от программы StarDict, вот его первые байты:
30 30 64 61 74 61 62 61 73 65 69 6E 66 6F 00 00

функция от ZENsan, возвращает строку до первого "00", т.е. :
"30 30 64 61 74 61 62 61 73 65 69 6E 66 6F" только в виде текста "00databaseinfo".

Как ни странно, но в файле нет маркеров $BBEF, $FEFF или $FFFE, но я точно знаю что файл в формате UTF-8.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо