我有一个用于存储二进制数据的Ansi字符串 - 0-255范围内的字节(我知道它应该是一个字节数组左右,但它们之间没有太大区别)。
我想通过Indy MIME(TIdEncoderMIME.EncodeString / TIdDecoderMIME.DecodeString)传递这个“二进制字符串”,并获得一个人类可读的 ANSI 字符串。
如果我使用IndyTextEncoding_8Bit编码,我认为Encode / DecodeString的输出将是一个只包含ANSI字符的字符串。但是我错了!
那么,如何用Indy Mime编码二进制数据(类似于application/octet-stream)?
答案 0 :(得分:4)
不要将AnsiString
用于二进制数据!
AnsiString
不是二进制数据的合适容器,尤其是在像XE7这样的Unicode环境中。使用正确的字节容器,例如T(Id)Bytes
或TMemoryStream
。
您无法通过AnsiString
字符串方法传递TId(Encoder|Decoder)MIME
,仅UnicodeString
,因此隐式RTL Ansi< - > Unicode转换可能会损坏您的二进制数据。而是使用面向二进制的方法((Encode|Decode)Bytes()
,(Encode|Decode)Stream()
)。它们存在是有原因的。
话虽如此,Indy 10确实有一个TIdMemoryBufferStream
类(仅限桌面平台),所以如果你必须使用AnsiString
(你真的不应该),你可以把它包装成{ {1}}接口,无需在内存中创建额外的数据副本。例如:
TStream
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;