専門家が親切に提案したように、によってロードされたデータを取得するため
TStringStream.DataString
に使用することはできません。これは、のエンコーディングメソッドを呼び出すためです。たとえば、を呼び出し、次にを呼び出し、最後にを呼び出します。non-text
TStringStream.LoadFromFile
TStringStream.GetDataString
TEncoding
TMBCSEncoding
TMBCSEncoding.GetChars
TMBCSEncoding.UnicodeFromLocaleChars
Windows
MultiByteToWideChar
TBytesは、データバッファ/バイナリストレージとして使用することをお勧めします。(この目的のために、AnsiStringよりもTBytesをお勧めします。)
は、メソッドまたはプロパティ
bytes
から取得できます。いずれにせよ、検討する必要があります。TStringStream.ReadBuffer
TStringStream.Bytes
TStream.Size
================================================== ==
私はbase64のエンコード/デコードの目的でTStringStream
それを使用しようとしています。ここまたはここでの返信でDataString
示されているように、それは可能のようです。Nils Haeck
TStringStream.DataString
inTMainForm.QuestionOfString_StringStream
(No.2〜No.7)を使用すると、情報が破損している(つまり、元の情報と同じではない)という点で失敗します。しかし、ss_loaded_2.SaveToFile
(No.1)は元の情報を保存しており、TStringStream
デコードされた非テキストデータを内部で正しく保持していることを示していますか?DataStringの破損の考えられる理由についてコメントしていただけますか?Rob Kennedy
の親切な回答の中で、彼はbase64でデコードされた非テキストデータを保存する際に言及したstring
かansistring
、避けるべきであり、これは非常に理にかなっています。ただし、に示すようにTMainForm.QuestionOfString_NativeXML
、DecString
ofAnsiString
タイプにはデコードされたバイトが含まれているため、データをエンコードして戻すことができます。これは、AnsiStringがデコードされた非テキストデータをそのまま保持できることを意味しますか?David Heffernan
そしてRob Kennedy
bytes/TBytesについて親切にコメントしました。ただし、でbytes
抽出されたは、ののとTMainForm.QuestionOfString_NativeXML_Bytes_1
は異なります。(Base64でのエンコード/デコードの結果から、間違っています。上記の段落に基づいて、内部にそのままのバイトが含まれている必要があるため、混乱しますか?)考えられる理由についてコメントしていただけますか?TStringStream
Bytes
TMainForm.QuestionOfString_NativeXML_Bytes_2
TStringStream.Bytes
TStringStream
ご助力ありがとうございます!
PS:サンプルファイルはSkyDriveからダウンロードできます:REF_EncodedSample&REF_DecodedSample。(Zlibで圧縮された画像ファイル。)
PS:Delphi XE、Windows7(Delphi 7に戻ったTStringStreamにはLoadFromFileまたはSaveToFileがないようです。)
サンプルコード
unit uMainForm;
interface
uses
CodeSiteLogging,
NativeXml, // v3.10
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
procedure QuestionOfString_StringStream;
procedure QuestionOfString_NativeXML;
procedure QuestionOfString_NativeXML_Bytes_1;
procedure QuestionOfString_NativeXML_Bytes_2;
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
// http://stackoverflow.com/questions/773297/how-can-i-convert-tbytes-to-rawbytestring
function Convert(const Bytes: TBytes): RawByteString;
begin
SetLength(Result, Length(Bytes));
if Length(Bytes) > 0 then
begin
Move(Bytes[0], Result[1], Length(Bytes));
// SetCodePage(Result, CP_ACP, False);
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
QuestionOfString_StringStream;
QuestionOfString_NativeXML;
QuestionOfString_NativeXML_Bytes_1;
QuestionOfString_NativeXML_Bytes_2;
end;
// http://www.delphigroups.info/2/3/321962.html
// http://borland.newsgroups.archived.at/public.delphi.graphics/200712/0712125679.html
procedure TMainForm.QuestionOfString_StringStream;
var
ss_loaded_2, ss_loaded_3: TStringStream;
dataStr: AnsiString;
hexOfDataStr: AnsiString;
begin
ss_loaded_2 := TStringStream.Create();
// load the file containing Base64-decoded sample data
ss_loaded_2.LoadFromFile('REF_DecodedSample');
// 1
ss_loaded_2.SaveToFile('REF_DecodedSample_1_SavedByStringStream');
// 2
ss_loaded_3 := TStringStream.Create(ss_loaded_2.DataString);
ss_loaded_3.SaveToFile('REF_DecodedSample_2_SavedByStringStream');
// 3
ss_loaded_3.Free;
ss_loaded_3 := TStringStream.Create(ss_loaded_2.DataString, TEncoding.ASCII);
ss_loaded_3.SaveToFile('REF_DecodedSample_3_SavedByStringStream');
// 4
ss_loaded_3.Free;
ss_loaded_3 := TStringStream.Create(ss_loaded_2.DataString, TEncoding.UTF8);
ss_loaded_3.SaveToFile('REF_DecodedSample_4_SavedByStringStream');
// 5
ss_loaded_3.Free;
ss_loaded_3 := TStringStream.Create(AnsiString(ss_loaded_2.DataString));
ss_loaded_3.SaveToFile('REF_DecodedSample_5_SavedByStringStream');
// 6
ss_loaded_3.Free;
ss_loaded_3 := TStringStream.Create(UTF8String(ss_loaded_2.DataString));
ss_loaded_3.SaveToFile('REF_DecodedSample_6_SavedByStringStream');
// 7
dataStr := ss_loaded_2.DataString;
SetLength(hexOfDataStr, 2 * Length(dataStr));
BinToHex(@dataStr[1], PAnsiChar(@hexOfDataStr[1]), Length(dataStr));
CodeSite.Send(hexOfDataStr);
ss_loaded_2.Free;
ss_loaded_3.Free;
end;
// http://www.simdesign.nl/forum/viewtopic.php?f=2&t=1311
procedure TMainForm.QuestionOfString_NativeXML;
var
LEnc, LDec: integer;
EncStream: TMemoryStream;
DecStream: TMemoryStream;
EncString: AnsiString;
DecString: AnsiString;
begin
// encode and decode streams
EncStream := TMemoryStream.Create;
DecStream := TMemoryStream.Create;
try
// load BASE64-encoded data
EncStream.LoadFromFile('REF_EncodedSample');
LEnc := EncStream.Size;
SetLength(EncString, LEnc);
EncStream.Read(EncString[1], LEnc);
// decode BASE64-encoded data, after removing control chars
DecString := DecodeBase64(sdRemoveControlChars(EncString));
LDec := length(DecString);
DecStream.Write(DecString[1], LDec);
// save the decoded data
DecStream.SaveToFile('REF_DecodedSample_7_SavedByNativeXml');
// EncString := sdAddControlChars(EncodeBase64(DecString), #$0D#$0A);
EncString := EncodeBase64(DecString);
// clear and resave encode stream as a copy
EncStream.Clear;
EncStream.Write(EncString[1], Length(EncString));
EncStream.SaveToFile('REF_EncodedSampleCopy');
finally
EncStream.Free;
DecStream.Free;
end;
end;
procedure TMainForm.QuestionOfString_NativeXML_Bytes_1;
var
LEnc, LDec: integer;
EncStream: TMemoryStream;
DecStream: TMemoryStream;
EncString: AnsiString;
DecString: AnsiString;
DecBytes: TBytes;
begin
// encode and decode streams
EncStream := TMemoryStream.Create;
DecStream := TMemoryStream.Create;
try
// load BASE64-decoded data
DecStream.LoadFromFile('REF_DecodedSample');
LDec := DecStream.Size;
SetLength(DecBytes, LDec);
DecStream.Read(DecBytes[0], LDec);
EncString := EncodeBase64(Convert(DecBytes));
// clear and resave encode stream as a copy
EncStream.Write(EncString[1], Length(EncString));
EncStream.SaveToFile('REF_EncodedSampleCopy_Bytes_1');
finally
EncStream.Free;
DecStream.Free;
end;
end;
procedure TMainForm.QuestionOfString_NativeXML_Bytes_2;
var
LEnc, LDec: integer;
EncStream: TMemoryStream;
DecStream: TStringStream;
EncString: AnsiString;
DecString: AnsiString;
DecBytes: TBytes;
begin
// encode and decode streams
EncStream := TMemoryStream.Create;
DecStream := TStringStream.Create;
try
// load BASE64-decoded data
DecStream.LoadFromFile('REF_DecodedSample');
DecBytes := DecStream.Bytes;
EncString := EncodeBase64(Convert(DecBytes));
// clear and resave encode stream as a copy
EncStream.Write(EncString[1], Length(EncString));
EncStream.SaveToFile('REF_EncodedSampleCopy_Bytes_2');
finally
EncStream.Free;
DecStream.Free;
end;
end;
end.