TClientDataSet читает двоичное поле в TStream

Я пробовал это всеми возможными способами, но, похоже, не могу решить эту проблему. Я работаю с DBExress в Delphi XE3, пишу сервер REST DataSnap.

У меня есть данные, хранящиеся в MSQL в двоичном (384) поле, и двоичный файл, насколько я знаю, такой же, как поле BLOB/Image, поскольку все это двоичные данные.

При попытке передать эти данные в TStream я получаю ошибку исключения и пробовал следующее

var
STemplate : TStream;
begin
......
Template := TBlobField.Create(cdsBSUserTemplates.FieldByName('bTemplate'));
TBlobField(cdsBSUserTemplates.FieldByName('bTemplate')).SaveToStream(STemplate); //exception
......
end;

и я пробовал

var
STemplate : TStream;
begin
......
Template := TBlobField.Create(cdsBSUserTemplates.FieldByName('bTemplate'));
STemplate := cdsBSUserTemplates.CreateBlobStream(Template, bmRead); //exception
......
end;

Я могу вернуть значение .AsString, но это байты, и тогда мне нужно попытаться исправить то, что я прочитал из этого поля.

Любая идея, что еще я могу попробовать?


person Stefan De Beer    schedule 06.05.2014    source источник


Ответы (1)


Ты слишком много работаешь. :-)

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

var
  Output: TMemoryStream;
  Fld: TBlobField;
begin
  // Use of variable makes it more readable
  Fld := cdsBSUserTemplates.FieldByName('bTemplate') as TBlobField;

  Output := TMemoryStream.Create;
  try
    Fld.SaveToStream(Output);
    Output.Position := 0;
    // Do whatever with the output stream
  finally
    Output.Free;
  end;
end;

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

var
  Output: TMemoryStream;
  Fld: TField;
  Bytes: TArray<Byte>;
begin
  Fld := ADOQuery1.FieldByName('bTemplate');
  Output := TMemoryStream.Create;
  try
    if Fld.IsBlob then
      TBlobField(Fld).SaveToStream(Output)
    else
    begin
      Fld.GetData(Bytes);
      Output.WriteData(Bytes, Length(Bytes));
    end;
    // Do whatever with output
  finally
    Output.Free;
  end;
end;
person Ken White    schedule 06.05.2014
comment
Template := cdsBSUserTemplates.FieldByName('bTemplate') as TBlobField — я получаю здесь ошибку приведения Invalid Type. Я уверен, что TSQLQuery или TClientDataSet не имеют правильного типа данных для этого поля. Рассмотрю это. - person Stefan De Beer; 06.05.2014
comment
Когда я проверяю тип поля, это TVarByteField, если это помогает - person Stefan De Beer; 06.05.2014
comment
@StefanDeBeer Вы должны были решить это прежде чем задавать вопрос - person Sir Rufo; 06.05.2014