WeG*_*ars 1 delphi encoding mime indy delphi-xe7
我有一个 Ansi 字符串,用于存储二进制数据 - 0-255 范围内的字节(我知道它应该是一个字节数组左右,但它们之间没有太大区别)。
我想通过 Indy MIME (TIdEncoderMIME.EncodeString / TIdDecoderMIME.DecodeString) 传递这个“二进制字符串”并获得人类可读的ANSI字符串。
我认为如果我使用 IndyTextEncoding_8Bit 编码,Encode/DecodeString 的输出将是一个仅包含 ANSI 字符的字符串。但是我错了!
那么,如何使用 Indy Mime 编码二进制数据(类似于application/octet-stream)?
不要用于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(而且您确实不应该),您可以将其包装在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;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1607 次 |
| 最近记录: |