如何使用 Indy Mime 对二进制数据进行编码?
How to encode binary data with Indy Mime?
我有一个用于存储二进制数据的 Ansi 字符串 - 字节在 0-255 范围内(我知道它应该是一个字节数组左右,但它们之间并没有太大区别)。
我想通过 Indy MIME (TIdEncoderMIME.EncodeString / TIdDecoderMIME.DecodeString) 传递这个 "binary string" 并获得人类可读的 ANSI 字符串。
我认为如果我使用 IndyTextEncoding_8Bit 编码,Encode/DecodeString 的输出将是一个只有 ANSI 字符的字符串。但是我错了!
那么,如何使用 Indy Mime 对二进制数据进行编码(类似于 application/octet-stream)?
不要对二进制数据使用 AnsiString
!
AnsiString
不是二进制数据的合适容器,尤其是在像 XE7 这样的 Unicode 环境中。使用 适当的 字节容器,例如 T(Id)Bytes
或 TMemoryStream
。
您不能通过 TId(Encoder|Decoder)MIME
字符串方法按原样传递 AnsiString
,只能 UnicodeString
,因此隐式 RTL Ansi< ->Unicode 转换可能会破坏您的二进制数据。请改用面向二进制的方法 ((Encode|Decode)Bytes()
、(Encode|Decode)Stream()
)。它们的存在是有原因的。
也就是说,Indy 10 确实有一个 TIdMemoryBufferStream
class(仅限桌面平台),所以如果您必须使用 AnsiString
(实际上您不应该),您可以将其包装在 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;
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;
我有一个用于存储二进制数据的 Ansi 字符串 - 字节在 0-255 范围内(我知道它应该是一个字节数组左右,但它们之间并没有太大区别)。
我想通过 Indy MIME (TIdEncoderMIME.EncodeString / TIdDecoderMIME.DecodeString) 传递这个 "binary string" 并获得人类可读的 ANSI 字符串。
我认为如果我使用 IndyTextEncoding_8Bit 编码,Encode/DecodeString 的输出将是一个只有 ANSI 字符的字符串。但是我错了!
那么,如何使用 Indy Mime 对二进制数据进行编码(类似于 application/octet-stream)?
不要对二进制数据使用 AnsiString
!
AnsiString
不是二进制数据的合适容器,尤其是在像 XE7 这样的 Unicode 环境中。使用 适当的 字节容器,例如 T(Id)Bytes
或 TMemoryStream
。
您不能通过 TId(Encoder|Decoder)MIME
字符串方法按原样传递 AnsiString
,只能 UnicodeString
,因此隐式 RTL Ansi< ->Unicode 转换可能会破坏您的二进制数据。请改用面向二进制的方法 ((Encode|Decode)Bytes()
、(Encode|Decode)Stream()
)。它们的存在是有原因的。
也就是说,Indy 10 确实有一个 TIdMemoryBufferStream
class(仅限桌面平台),所以如果您必须使用 AnsiString
(实际上您不应该),您可以将其包装在 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;
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;