對二進制數據不要使用AnsiString
!
AnsiString
不適合二進制數據的容器,特別是在像XE7這樣的Unicode環境中。代替使用正確的字節容器,如T(Id)Bytes
或TMemoryStream
。
你不可錯過AnsiString
原樣通過TId(Encoder|Decoder)MIME
字符串方法,只有UnicodeString
,所以隱含的RTL安思< - > Unicode轉換可能會損壞您的二進制數據。改爲使用面向二進制的方法((Encode|Decode)Bytes()
,(Encode|Decode)Stream()
)。他們的存在是有原因的。
話雖這麼說,印第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;
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;
感謝。我將我的代碼轉換爲使用TIDBytes。有用。但有一個問題:爲什麼不應該使用AnsiString來存儲二進制數據? AnsiString只不過是一個字節數組而已。只要你不把它轉換成字符串,一切都應該沒問題。 – Ampere
@mutex'AnsiString'不僅僅是一個字節數組。它還有一個相關的代碼頁,這就是當在傳遞'AnsiString'到'TIdEncoderMIME.EncodeString()''時傳遞'AnsiString'值時會導致二進制數據丟失/損壞的原因。另外,如果您需要將代碼遷移到移動設備,則「AnsiString」不可用(沒有第三方修補程序) –