1
votes

I have migrated my application from Delphi XE2 to Delphi 10.2.3.

I have used this instruction to read a blob field into TMemo component:

Memo1.Text := AnNote.FieldByName('ANBLOB').Value

I see chinese characters in Delphi 10.2, and in Latin characters in Delphi XE2.

If I use this instruction:

Memo1.Lines.Text := AnNote.FieldByName('ANBLOB').AsString

I see the character in Latin alphabet in Delphi 10.2, why is this?

2
How is the blob encoded?David Heffernan
The Blob is a Firebird field with charset ISO 8859_1Giovanna Cellitti
Perhaps it's best to read it into a byte array and then decode manually. Which isn't completely trivial because that encoding isn't a standard one to be used with TEncoding.David Heffernan
@DavidHeffernan you can use TEncoding.GetEncoding('ISO-8859-1') or TEncoding.GetEncoding(28591), just be sure to Free() the returned TEncoding object when you are done using it.Remy Lebeau

2 Answers

1
votes

Memo1.Text := AnNote.FieldByName('ANBLOB').Value

I see chinese characters in Delphi 10.2, and in Latin characters in Delphi XE2.

The TField.Value property returns a Variant.

In 10.2, that Variant likely contains just the raw data of the blob. When converting such a Variant to a String, all charset information is lost. You get "Chinese characters" (commonly known as "Mojibake") when raw ANSI bytes are mis-interpreted as UTF-16 bytes.

In XE2, that Variant likely contains a pre-decoded string instead of raw blob bytes.

You want the database driver to decode strings for you, using the charset from the database field's metadata. So you may be encountering a bug in the database driver in 10.2 that did not exist in XE2.

Memo1.Lines.Text := AnNote.FieldByName('ANBLOB').AsString

I see the character in Latin alphabet in Delphi 10.2, why is this?

TField.AsString allows the database driver to decode the field data using the field's charset metadata as needed.

-2
votes

Memo1.Text is a TCaption (an alias for UnicodeString).

FieldByName('FIELD').Value is a Variant.

It depends on your information that is stored in the blob field. FieldByName('Field').AsString converts your blob to a String if possible.

Hope that helps to answer your question: "why is this?"!

2 options for "how to do it":

  1. you stay with .AsString if there was no special reason for switching to .Value.

  2. handle different data types, like a Picture, as shown here:

    Delphi load image save as blob in a sql database