简体   繁体   中英

How to encode binary data with Indy Mime?

I have an Ansi string that I use to store binary data - bytes in 0-255 range (I know it should be a Byte array or so, but it is not much difference between them).
I want to pass this "binary string" through Indy MIME (TIdEncoderMIME.EncodeString / TIdDecoderMIME.DecodeString) and obtain a human-readable ANSI string.

I thought that the output of Encode/DecodeString will be a string that has only ANSI characters in it if I use IndyTextEncoding_8Bit encoding. But I was wrong!

so, how to encode binary data with Indy Mime (something similar to application/octet-stream )?

DONT use AnsiString for binary data!

AnsiString is not an appropriate container for binary data, especially in a Unicode environment like XE7. Use a proper byte container, like T(Id)Bytes or TMemoryStream instead.

You can't pass AnsiString as-is through the TId(Encoder|Decoder)MIME string methods, only UnicodeString , so implicit RTL Ansi<->Unicode conversions are likely to corrupt your binary data. Use the binary-oriented methods instead ( (Encode|Decode)Bytes() , (Encode|Decode)Stream() ). They exist for a reason.

That being said, Indy 10 does have a TIdMemoryBufferStream class (desktop platforms only), so if you MUST use AnsiString (and you really shouldn't), you can wrap it in a TStream interface without having to make additional copies of data in memory. For example:

var
  Binary: AnsiString;
  Strm: TIdMemoryBufferStream;
  Base64: String;
begin
  Binary := ...; // binary data
  Strm := TIdMemoryBufferStream.Create(PAnsiChar(Binary), Length(Binary));
  try
    Base64 := TIdEncoderMIME.EncodeStream(Strm);
  finally
    Strm.Free;
  end;
  // use Base64 as needed...
end;

var
  Base64: String;
  Strm: TIdMemoryBufferStream;
  Binary: AnsiString;
begin
  Base64 := ...; // encoded data
  SetLength(Binary, (Length(Base64) div 4) * 3);
  Strm := TIdMemoryBufferStream.Create(PAnsiChar(Binary), Length(Binary));
  try
    TIdDecoderMIME.DecodeStream(Base64, Strm);
    SetLength(Binary, Strm.Size);
    SetCodePage(PRawByteString(@Binary)^, 28591, False);
  finally
    Strm.Free;
  end;
  // use Binary as needed...
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM