Перейти к содержанию
Fire Monkey от А до Я
  • 0

No mapping for the Unicode character exists in the target multi-byte code page


Roma77751

Вопрос

Всем доброго времени суток! Очень нужна помощь знатоков. Знаю что вопрос поднимался на эту тему неоднократно, но я не смог разобраться с кодировками. Задача в следующем: делаю get запрос на сайт. полученные данные сохраняю в html файл. корректирую и открываю исправленный вариант в webbrowser.

 

вот код:

http:=thttpsend.Create;

p:=TStringStream.Create('', TEncoding.utf8);
http.Headers.Add('content-type: application/json; charset="UTF-8"');
http.MimeType:='application/x-www-form-urlencoded'  ;
http.UserAgent:='Mozilla/5.0 (Windows NT 6.0; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0';
if http.HTTPMethod('get','http://www.mail.ru/')  then   p.LoadFromStream(http.document);
p.SaveToFile('sdcard/Android/data/test.html');
 
с таким кодом отображаются закорючки, но это пол беды...в tstringstream толком не могу скорректировать код как мне надо, в нем я так понял редактируется текст по буквам. а мне надо построчно. Использую вместо tstringstream tstringlist или memo.lines выдает ошибку "No mapping for the Unicode character exists in the target multi-byte code page".
Плз кто знает объясните этот прикол с кодировками, очень хочу понять...
Изменено пользователем Andrey Efimov
Добавил тег "Код"
Ссылка на комментарий

Рекомендуемые сообщения

  • 0

1. Код закинь в теги

[ code=auto:0] [/ code]

 

2. Насчет построчного редактирования - почему то неуверен что это вам нужно

3. А теперь по делу - пробуй загрузить в мемо1 - без указания кодировки.

4. Посмотри снифером заголовки документа от сервера - в каком формате тебе присылает сервак.(ну или System.Net.HttpClient.THttpClient.Head) 

5. Смотри мою тему

 

//А что за библиотека для работы с сетью у вас? Похоже на синапс....

Изменено пользователем Сысоев Максим
Ссылка на комментарий
  • 0

1. Код закинь в теги

[ code=auto:0] [/ code]

 

2. Насчет построчного редактирования - почему то неуверен что это вам нужно

3. А теперь по делу - пробуй загрузить в мемо1 - без указания кодировки.

4. Посмотри снифером заголовки документа от сервера - в каком формате тебе присылает сервак.(ну или System.Net.HttpClient.THttpClient.Head) 

5. Смотри мою тему

 

//А что за библиотека для работы с сетью у вас? Похоже на синапс....

 

 

Да, это синапс.

Приходит все в UTF8 однозначно.

кидал в мемо с винды все работает(в тексте закорючки), делал memo1.text:=utf8toansi(memo1.text); и в мемо все норм. А в андроиде ничего не выходит, грубо говоря текст с кодировкой utf8 сую в мемо(без декодировок) выдает ошибку "No mapping for the Unicode character exists in the target multi-byte code page".

По поводу тэга, что он делает?

Ссылка на комментарий
  • 0

Насчет синапса - я упустил или его портировали на андроид? 

Насколько я знаю - на данный момент поддерживают андроид: InDy, ICS и системная либа: System.Net

С синапсом давно не работал, так что могу посоветовать последню библиотеку выше. 

Ссылка на комментарий
  • 0

Насчет синапса - я упустил или его портировали на андроид? 

Насколько я знаю - на данный момент поддерживают андроид: InDy, ICS и системная либа: System.Net

С синапсом давно не работал, так что могу посоветовать последню библиотеку выше. 

Indi мне показалась сильно мудреная,что то как то не захотел с ней разбираться. Синапс больше по душе. Да кое как отыскал для андроида, писали что кривовато работает, но я пока сбоев не обнаружил. 

Ссылка на комментарий
  • 0

что с кодировками делать, вопрос не дает покоя. почему tstringstream может через webbrowser вывести корявый текст а через tstringlist или memo выдает ошибку...?

Ссылка на комментарий
  • 0

Потому что в приведенном коде StringStream не задействует работу со строками, а работает как TByteStream, наследником коего он, собственно, и является. А StringList пытается преобразовать набор байт в символы используя TEncoding, что и приводит к ошибке.

Вердикт один - несовпадение кодировки. Видимо, сервер отдает не UTF8, принятый по умолчанию на Android.

Ссылка на комментарий
  • 0

Потому что в приведенном коде StringStream не задействует работу со строками, а работает как TByteStream, наследником коего он, собственно, и является. А StringList пытается преобразовать набор байт в символы используя TEncoding, что и приводит к ошибке.

Вердикт один - несовпадение кодировки. Видимо, сервер отдает не UTF8, принятый по умолчанию на Android.

Сервер выдает utf8. и используя stringstream ошибок нет. все загружается как надо(только русские буквы закорючками изображены) Только мне нужно работать именно со строками...ну или проще можно поставить вопрос: как текст UTF8 кодировки  засунуть в memo.в винде проблем нет, в андроиде выдает ошибку...уже массу всего перечитал, перепробовал, ничего не получается.  

Ссылка на комментарий
  • 0

 

Сервер выдает utf8. и используя stringstream ошибок нет. все загружается как надо(только русские буквы закорючками изображены) Только мне нужно работать именно со строками...ну или проще можно поставить вопрос: как текст UTF8 кодировки  засунуть в memo.в винде проблем нет, в андроиде выдает ошибку...уже массу всего перечитал, перепробовал, ничего не получается.  

 

Если русские символы - закорючки, значит, не UTF8:

- либо у вас при загрузке в StringList и Memo,

- либо у сервера.

Написать в ответе Content-Type:"text/html; charset=utf-8", а содержимое отдать в UTF16 ума много не надо.

Повторю - в StringStream ошибки нет, потому что в приведенном коде не используется работа со строками. Попробуйте получить p.DataString - ошибка возникнет?

 

По поводу замечания "в memo в винде проблем нет" - винда использует UTF16. И Delphi под винду тоже использует UTF16. Возможно, дело в этом.

 

Update: вполне возможно, проблема прячется внутри портированного на мобильную платформу синапса. Предположительно, после получения ответа от сервера может вызываться перекодировка UTF8 ->UTF16 и уже бинарное содержимое UTF16 запихиваться в выходной поток.

Ну, это из разряда фантазий уже, не работал я с синапсами.

Изменено пользователем kami
Ссылка на комментарий
  • 0

 

 

Сервер выдает utf8. и используя stringstream ошибок нет. все загружается как надо(только русские буквы закорючками изображены) Только мне нужно работать именно со строками...ну или проще можно поставить вопрос: как текст UTF8 кодировки  засунуть в memo.в винде проблем нет, в андроиде выдает ошибку...уже массу всего перечитал, перепробовал, ничего не получается.  

 

Если русские символы - закорючки, значит, не UTF8:

- либо у вас при загрузке в StringList и Memo,

- либо у сервера.

Написать в ответе Content-Type:"text/html; charset=utf-8", а содержимое отдать в UTF16 ума много не надо.

Повторю - в StringStream ошибки нет, потому что в приведенном коде не используется работа со строками. Попробуйте получить p.DataString - ошибка возникнет?

 

По поводу замечания "в memo в винде проблем нет" - винда использует UTF16. И Delphi под винду тоже использует UTF16. Возможно, дело в этом.

 

 

Не уверен что все так... ну допустим с сервера приходит другая кодировка, но я пробовал и так  s.loadfromstream(http.document,Tencoding.UTF8).(s-это stringlist)...так выводится та же ошибка,  поставил вместо UTF8 - ANSI  хотя сколько читал что на анроиде только utf8...ну и ошибка пропала...вообще не пойму, как не крутил не могу вывести русские буквы,одни иероглифы...и с ASCII тоже ошибки нет....но тоже русского нет(

Ссылка на комментарий
  • 0
  • Модераторы

1) Сервер Ваш? если да, то в php указать header('Content-Type: text/html; charset=utf-8');

2) посмореть в хидерах или снифером что приходит.

По умолчанию в Delphi под Windows кодировка по умолчанию ANSI, Остальные UTF-8

 

Проверьте этим кодом кодировку

var
  Stream: TBytesStream;
  Size: Integer;
  Buffer: TBytes;
  Encoding: TEncoding;
begin
  Stream := TBytesStream.Create;
  try
    Stream.LoadFromStream(ТУТ ВАШИ ДАННЫЕ);
    Buffer := Stream.Bytes;
    Size := TEncoding.GetBufferEncoding(Buffer, Encoding, TEncoding.Default);
  finally
    Freeandnil(Stream);
  end;
  ShowMessage(Encoding.EncodingName);
end;
Ссылка на комментарий
  • 0

1) Сервер Ваш? если да, то в php указать header('Content-Type: text/html; charset=utf-8');

2) посмореть в хидерах или снифером что приходит.

По умолчанию в Delphi под Windows кодировка по умолчанию ANSI, Остальные UTF-8

 

Проверьте этим кодом кодировку

var
  Stream: TBytesStream;
  Size: Integer;
  Buffer: TBytes;
  Encoding: TEncoding;
begin
  Stream := TBytesStream.Create;
  try
    Stream.LoadFromStream(ТУТ ВАШИ ДАННЫЕ);
    Buffer := Stream.Bytes;
    Size := TEncoding.GetBufferEncoding(Buffer, Encoding, TEncoding.Default);
  finally
    Freeandnil(Stream);
  end;
  ShowMessage(Encoding.EncodingName);
end;

1)нет сервер чужой.

2) снифером(делая запрос не с телефона а с компа) смотрел, в ответе есть строка <meta http-equiv="Content-Type" content="text/html; charset=utf-8">.(в нем из под винды кстати тоже русские буквы закорючки)\

3) сунул код в прогу вывел UTF8.

 

Какие еще мысли будут? всю ночь не спал, ковырялся...так XE7 замучал что с утра он отказался компилировать,пришлось перезапустить, перезапустил-перестал видеть android устройства, только после 2-го перезапуска норм заработал. Вообще XE7 только поставил, но впечатления не очень честно говоря...Delphi 7 хоть и старая но надежная и стабильная... 

post-2162-0-24719800-1457428216_thumb.jp

post-2162-0-01555300-1457428610_thumb.jp

Ссылка на комментарий
  • 0
  • Модераторы

а что скриншот с телефона платная услуга?)

 

что за сайт такой? http://www.mail.ru/?

Изменено пользователем ZuBy
Ссылка на комментарий
  • 0

а что скриншот с телефона платная услуга?)

 

)))верно, затупил, говорю ночь не спал...подумал лень перекидывать с телефона скрин и не сообразил что он итак уже подключен :lol:

Ссылка на комментарий
  • 0

Поклонники синапса, извините. Roma77751 - у вас ничего не получится с синапсом. Если честно, я не понимаю, как он работает с любой Delphi версии больше 2007.

Возможно, в полной библиотеке все нормально и это недостатки "портированной" для мобильных платформ.

 

Вкратце - полный швах в модуле synabyte, класс (вернее record) TSynaBytes. Несмотря на явно используемую директиву {$IFDEF UNICODE}, считается что 1 символ = 1 байт. Отсюда все проблемы

 

Roma77751, уходите с этой библиотеки. Не будет она работать на мобильных платформах.

Ссылка на комментарий
  • 0

Поклонники синапса, извините. Roma77751 - у вас ничего не получится с синапсом. Если честно, я не понимаю, как он работает с любой Delphi версии больше 2007.

Возможно, в полной библиотеке все нормально и это недостатки "портированной" для мобильных платформ.

 

Вкратце - полный швах в модуле synabyte, класс (вернее record) TSynaBytes. Несмотря на явно используемую директиву {$IFDEF UNICODE}, считается что 1 символ = 1 байт. Отсюда все проблемы

 

Roma77751, уходите с этой библиотеки. Не будет она работать на мобильных платформах.

 

Вы уверены что проблема в синапсе? :(  так долго его искал...

если да то, какую библиотеку посоветуете, кроме indy...indy что то я понять нормально не смог. 

вопрос пока не буду закрывать, попробую все тоже самое с библиотекой которую вы посоветуете и выложу результат. 

Ссылка на комментарий
  • 0

Поклонники синапса, извините. Roma77751 - у вас ничего не получится с синапсом. Если честно, я не понимаю, как он работает с любой Delphi версии больше 2007.

Возможно, в полной библиотеке все нормально и это недостатки "портированной" для мобильных платформ.

 

Вкратце - полный швах в модуле synabyte, класс (вернее record) TSynaBytes. Несмотря на явно используемую директиву {$IFDEF UNICODE}, считается что 1 символ = 1 байт. Отсюда все проблемы

 

Roma77751, уходите с этой библиотеки. Не будет она работать на мобильных платформах.

 

может все таки можно как то перекодировать текст? 

или в коде самого синапса покопаться...?

Изменено пользователем Roma77751
Ссылка на комментарий
  • 0
  • Модераторы

вот так примерно будет выглядеть ваш код на indy

function idHttpGet(const aURL: string): string;
// uses idHttp
var
  Resp: TBytesStream;
begin
  Result := '';
  with TidHTTP.Create(nil) do
  begin
    HandleRedirects := true;
    Resp := TBytesStream.Create;
    Get(aURL, Resp);
    // Resp.SaveToFile('sdcard/Android/data/test.html'); // сохранение
    Resp.Seek(0, 0);
    Result := StringOf(Resp.Bytes);
    Resp.Free;
    Free;
  end;
end;

а вот так на Net.HTTPClient

function idHttpGet2(const aURL: string): string;
// uses  System.Net.HttpClient, System.Net.HttpClientComponent, System.Net.URLClient;
var
  Resp: TBytesStream;
begin
  Result := '';
  with TNetHTTPClient.Create(nil) do
  begin
    Resp := TBytesStream.Create;
    Get(aURL, Resp);
//    Resp.SaveToFile('sdcard/Android/data/test.html'); // сохранение
    Resp.Seek(0, 0);
    Result := StringOf(Resp.Bytes);
    Resp.Free;
    Free;
  end;
end;
Ссылка на комментарий
  • 0

может все таки можно как то перекодировать текст? 

После того, как синапс потерял (реально потерял) половину (или больше, если мы говорим об иероглифах) значимых байт в ответе сервера? Нет.

 

или в коде самого синапса покопаться...?

А кому это нужно? Вы, судя по всему, не сможете. Остальные сидят на качественно адаптированных библиотеках, официально поддерживающих кросс-платформенность.

 

Последуйте тому, что Вам советуют - уходите от синапса на что-либо другое. Примеры дал Zuby.

Изменено пользователем kami
Ссылка на комментарий
  • 0

Ребят спасибо большое что уделили внимание и помогли решить мой вопрос. Отдельное спасибо kami, ZuBy. Все дело было действительно в кривом синапсе. Если б не вы парни не знаю сколько бы еще ночей просидел безрезультатно, уж в синапс бы не полез, мозгом не дорос :) kami ты крутой, понял сразу где собака зарыта :D

Сделал все через indy, пошло как по маслу)

Ссылка на комментарий
  • 0

Сорри что поднимаю эту тему, но вылазиет аналогичная (см. тему) ошибка. Проблема заключается в трех-строчках:

Memo1.Lines.LoadFromFile(TPath.Combine(TPath.GetDocumentsPath, 'my.html')); // загружаем в мемо текст
Memo1.Lines.SaveToFile(TPath.Combine(TPath.GetDocumentsPath, 'temp.html'));  //сохраняем в файл
WebBrowser1.Navigate('file:///'+TPath.Combine(TPath.GetDocumentsPath, 'temp.html')); //пытаемся открыть

при компилировании в windows - все норм, на андроиде - проблема с кодировками <_< пробовал тысячи способв - но как будто об стенку. Помогите!! :unsure: 

если первую строчку заменить на типа memo1.text:='траляля'; то код становится рабочим

Ссылка на комментарий
  • 0
  • Модераторы

Используйте TEncoding.UTF8

Memo1.Lines.LoadFromFile(TPath.Combine(TPath.GetDocumentsPath, 'my.html'), TEncoding.UTF8); 
Memo1.Lines.SaveToFile(TPath.Combine(TPath.GetDocumentsPath, 'temp.html'), TEncoding.UTF8); 

 

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...