unicode対応のテキストファイル

解決


NAGSYS  2010-02-16 17:45:09  No: 37648  IP: 192.*.*.*

Delphi2009を使ってます。

unicode文字をテキストファイルに出力したいんですが、下記のようにすると、unicode文字が?に文字化けしてしまいます。

  AssignFile(F, 'TEXT.TXT');
  ReWrite(F);
  WriteLn(F, '10㎥'); // 立法メートル
  Flush(F);
  CloseFile(F);

TStringListのSaveToFileで出力してもだめでした。

テキストファイルをメモ帳で文字コード=unicodeにして新規作成し、追加モードで出力しようとしましたが、今度は全ての文字が文字化けします。

設定ファイル(ini)の場合は、プログラムで作成するとうまくいきませんが、メモ帳で文字コードをunicodeにしてから書き込むと大丈夫のようです。

プログラムでunicode対応のテキストファイルを作成するにはどうしたらいいんでしょうか?
よろしくお願いします。

編集 削除
うにこ〜ど  2010-02-16 18:14:43  No: 37649  IP: 192.*.*.*

MECSUtils
http://homepage1.nifty.com/ht_deko/tech021.html#tech050

でユニコード扱ってみる

編集 削除
totonica  URL  2010-02-16 18:26:13  No: 37650  IP: 192.*.*.*

こんにちは。

TStringListであればTEncodingと併用すれば簡単にUnicodeで出力できます。
SaveToFileメソッドの第2引数にTEncoding.Unicodeと指定すればOKです。
http://totonica.s41.xrea.com/doc/delphi_tiburon/doc_unicode/tencoding_textio.htm

iniファイルの場合はTIniFileとTMemIniFileで取り扱いが微妙に異なります。
http://totonica.s41.xrea.com/doc/delphi_tiburon/doc_unicode/inifiles_unicode.htm

編集 削除
NAGSYS  2010-02-18 14:43:54  No: 37651  IP: 192.*.*.*

うにこ〜どさん、totonicaさん
ありがとうございます。

TStringListとiniファイルはうまくいくました。

AssignFileを使ってファイルに書き込むのは難しそうです。
ファイルを2つ作ってDOSコマンドで結合できるかと思ったんですがダメでした。

編集 削除
totonica  URL  2010-02-18 15:45:46  No: 37652  IP: 192.*.*.*

こんにちは。

> AssignFileを使ってファイルに書き込むのは難しそうです。
一般向けのドキュメントにはどこにも記載がありませんが、
Readln / Writeln等はUnicode非対応なのが仕様です。
Unicodeのファイル入出力はTStringListやストリーム等でTEncodingを併用するしかなさそうです。

編集 削除
NAGSYS  2010-02-18 16:00:18  No: 37653  IP: 192.*.*.*

> Readln / Writeln等はUnicode非対応なのが仕様です。

やはりそうでしたか。
ストリームでの出力方法を調べてみます。

ありがとうございました。

編集 削除
totonica  URL  2010-02-18 17:00:14  No: 37654  IP: 192.*.*.*

こんにちは。

> ファイルを2つ作ってDOSコマンドで結合できるかと思ったんですがダメでした。

ご希望に添っているかは分かりませんが、
TFileStreamを使って2つのUnicodeファイルを結合するコードを作ってみました。

例:
プログラムの実行フォルダにtext_a.txt、text_b.txtというUnicode(UTF-16LE)テキストファイルがあり、
text_a.txt -> text_b.txtの順に結合してtext_c.txtとして出力する。

var
  FP: String;
  RFS,WFS: TFileStream;
begin
  FP := ExtractFilePath(ParamStr(0));
  if (FileExists(FP+'text_a.txt')) and (FileExists(FP+'text_b.txt')) then
  begin
    WFS := TFileStream.Create(FP+'text_c.txt',fmCreate);
    try
      {1つめのファイル}
      RFS := TFileStream.Create(FP+'text_a.txt',fmOpenRead);
      try        
        WFS.CopyFrom(RFS,0);//全てコピーする
      finally
        RFS.Free;
      end;
      {2つめのファイル}
      RFS := TFileStream.Create(FP+'text_b.txt',fmOpenRead);
      try
        RFS.Position := 2;//BOMをスルーする
        WFS.CopyFrom(RFS,RFS.Size - 2);
      finally
        RFS.Free;
      end;
    finally
      WFS.Free;
    end;
  end;
end;

TFileStreamを使う場合は2つめのファイルをコピーする際にBOMをスルーしなければならないのがポイントです。

編集 削除
NAGSYS  2010-02-19 17:17:05  No: 37655  IP: 192.*.*.*

totonicaさん  ありがとうございます。

これができれば、大きいサイズのファイルも分割して出力し、あとで結合するという方法がとれます。
大変たすかりました。

編集 削除