WideString(Unicode)をTMemoryStreamに展開する方法がわかりません。
以下のコードを書いて試していますが、上手くファイル出力できません。
(ゴミが入ってしまう?)
procedure OutFile_UNI(OutputContent, OutputFileName : WideString);
var
Buffer: PByte;
len : dWord;
msIn : TMemoryStream;
fsOut : TFileStream;
endFlg: Boolean;
begin
//**** ここがうまくいかない? ****
// WideStringの値をTMemoryStreamに保持する
msIn := TMemoryStream.Create;
msIn.Write(PWChar(OutputContent)^, Length(OutputContent)*sizeof(PWChar) );
msIn.Position := 0;
//**********************************
fsOut:= TFileStream.Create(OutputFileName, fmCreate);
try
GetMem(Buffer, 512);
repeat
endFlg := (msIn.Position >= msIn.Size);
if endFlg then break;
len := msIn.Read(Buffer^, 512);
// **** バッファ(Buffer)に対する加工処理 ****
fsOut.Write(Buffer^, len);
until endFlg;
FreeMem(Buffer, 512);
finally
msIn.Free;
fsOut.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
strTmp : WideString;
begin
strTmp := '文字列を書き込み!'+#13#10+'書き込みテストです';
// [NG] Unicodeファイルの出力
OutFile_UNI(strTmp, 'unicode.txt');
end;
TMemoryStreamからTFileStreamにバッファを格納しているのは、特別なバッファ処理があるためで、単にUnicode文字列をファイル出力したいのではありません。
ですので何とかWideStringの値をTMemoryStreamに格納したい次第です。
ちなみにString(SJIS)の場合は上手く行きました。
procedure OutFile_SJIS(OutputContent, OutputFileName : String);
var
Buffer: PByte;
len : dWord;
msIn : TMemoryStream;
fsOut : TFileStream;
endFlg: Boolean;
begin
// Stringの値をTMemoryStreamに保持する
msIn := TMemoryStream.Create;
msIn.Write(PChar(OutputContent)^, Length(OutputContent) );
msIn.Position := 0;
fsOut:= TFileStream.Create(OutputFileName, fmCreate);
try
GetMem(Buffer, 512);
repeat
endFlg := (msIn.Position >= msIn.Size);
if endFlg then break;
len := msIn.Read(Buffer^, 512);
// **** バッファ(Buffer)に対する加工処理 ****
fsOut.Write(Buffer^, len);
until endFlg;
FreeMem(Buffer, 512);
finally
msIn.Free;
fsOut.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
strTmp : String;
begin
strTmp := '文字列を書き込み!'+#13#10+'書き込みテストです';
// [OK] SJISファイルの出力
OutFile_SJIS(strTmp, 'unicode.txt');
end;
環境はTurbo Delphiです。
すみませんが、お知恵をお借り出来れば幸いです。
こんにちは。
"WideString 文字列をデータとして書き出す" のではなく、
"Unicode (UTF-16LE) のテキストファイルとして書き出す" のであれば、
ファイル先頭の BOM が足りないのではないでしょうか?
fsOut:= TFileStream.Create(OutputFileName, fmCreate);
try
fsOut.Write(#$FF#$FE, 2); // <- BOM を追加
...
[Unicode (Delphi VCL FAQ)]
http://ht-deko.minim.ne.jp/tech013.html
DEKO様
早速の書き込みありがとうございました。
> Unicode (UTF-16LE) のテキストファイルとして書き出す
はい、最終的にUTF-16で書き出すことになります。
> ファイル先頭の BOM が足りないのではないでしょうか?
BOMの追加のコードを埋め込みましたが、やはりうまくいきません。
うまくいかない現象としては、サンプルコードを実行し、
ファイルの中身を確認すると、以下のようになってしまいます。
------
文字列を書き込み!
書き込みテストですxxxxxxxxx
------
(xxxxxxxxxの部分は文字化けで、文字コードはUTF-16)
個人的に、サンプルコードの以下の箇所の
WideStringの値をTMemoryStreamにWirteしている箇所が
良くないと思っていますが、いかがでしょうか。
------
msIn.Write(PWChar(OutputContent)^, Length(OutputContent)*sizeof(PWChar) );
------
(サイズの指定がおかしい?)
> [Unicode (Delphi VCL FAQ)]
Unicodeの詳しい解説のリンクありがとうございました。
私はUnicodeに対し詳しいわけではありませんので、
他のサイトも含めて少しずつ仕組みを理解したいと思います。
度々すみませんが、お知恵をお借り出来れば幸いです。
msIn.Write(PWChar(OutputContent)^, Length(OutputContent)*sizeof(PWChar) );
PWChar じゃなくて WChar だろ
KHE00221様
書き込みありがとうございました。
ご指摘の通り修正しましたところ、正常に動作しました!
msIn.Write(PWChar(OutputContent)^, Length(OutputContent)*sizeof(PWChar) );
↓
msIn.Write(PWChar(OutputContent)^, Length(OutputContent)*sizeof(WChar) );
本当にありがとうございました、助かりました。
ツイート | ![]() |