В целевой многобайтовой кодовой странице нет сопоставления для символа Unicode: как преобразовать MemoryStream в String - PullRequest
1 голос
/ 14 июня 2019

Моя цель - конвертировать TMemoryStream в string. У меня есть этот код, чтобы получить данные в TMemoryStream:

var
  idHttp : TIdHTTPEx;
  url : string;
  slTemp : TStringList;
  memoryStream : TMemoryStream;
begin
  try

    idHttp := TIdHTTPEx.Create(nil);
    slTemp := TStringList.Create;
    memoryStream := TMemoryStream.Create;
    try
      url := GetURL;
      SetParams(slTemp);

  idHttp.Request.Accept := 'application/json, text/javascript, */*; q=0.01';
  idHttp.Request.AcceptEncoding := 'gzip, deflate, br';
  idHttp.Request.AcceptLanguage := 'en-US,en;q=0.9';
  idHttp.Request.CacheControl := 'no-cache';
  idHttp.Request.Connection := 'keep-alive';
  idHttp.Request.ContentLength := 16;
  idHttp.Request.ContentType := 'application/x-www-form-urlencoded; charset=UTF-8';

      idHttp.Post(url, slTemp, memoryStream);
      Result := MemoryStreamToString(memoryStream);
    finally
      memoryStream.Free;
      slTemp.Free;
      idHttp.Free;
    end;

  except on E : Exception do
    begin
      Result := 'e:' + E.Message;
    end;
  end;
end;

А это мой код для преобразования его в string:

function MemoryStreamToString(MemoryStream : TMemoryStream): string;
var
  StringStream: TStringStream;
begin
  Result:='';

    StringStream:= TStringStream.Create('', TEncoding.UTF8);
  try
    MemoryStream.Position := 0;
    StringStream.CopyFrom(MemoryStream, MemoryStream.Size);

    Result:= StringStream.DataString;
    Result := Result;
  finally
    FreeAndNil(StringStream);
  end;

end;

Моя функция прекрасно работает в большинстве случаев преобразования, но не в этом. Я проверил эти ссылки: link1 , link2 , но они отличаются от моей ситуации. Я тоже попробовал link3 , но все равно не получилось.

Есть идеи, как решить проблему?

1 Ответ

4 голосов
/ 14 июня 2019

Вам не нужно декодировать необработанные данные вручную. Просто позволь TIdHTTP сделать это за тебя. Метод Post() имеет перегрузку, которая возвращает декодированную строку:

Result := idHttp.Post(url, slTemp);

Также вам необходимо полностью избавиться от этой строки:

idHttp.Request.AcceptEncoding := 'gzip, deflate, br';

В противном случае TIdHTTP не сможет правильно декодировать ответ, если сервер решит отправить сжатый ответ. Вы вручную предоставляете серверу разрешение на это, но не настраиваете свойство TIdHTTP.Compressor, поэтому TIdHTTP может обрабатывать декомпрессию. Не устанавливайте AcceptEncoding вручную, если вы не хотите и не можете вручную обнаружить и декодировать ответ, который был фактически закодирован в одном из указанных вами форматов. В противном случае, просто позвольте TIdHTTP внутренне управлять свойством AcceptEncoding, основываясь на его реальных возможностях.

...