write命令実行時のファイル書き込みテキストエンコーディングが10.8で変更に
AppleScriptのWrite命令(ファイルへの書き込みを実行)にオプションを付けることでファイル書き込み時のテキストエンコーディングを変更することができるようになっています。
Appleとしては、テキストエンコーディングを「存在しないもの」として、AppleScriptの言語処理系から「隠ぺい」するというのがねらいです。そのために、いま何の文字コードを使っているかが見えにくいといいますか、確認する方法がないので不便なケースが多々あります。
しかし、write命令に「as XXXXX」と指定を行うことで、ある程度テキストエンコーディングの指定が可能、という指摘を本Blogのコメント欄でいただきました。OSAXで文字コード指定を行ってファイルの読み書きを行うもの(Satimage OSAX)もありますし、その種類のサブルーチンをいろいろと揃えてきました。
コメント欄でご指摘のあったすべての方法を、実際にOS X 10.8.2上で試してみたところ……予想外にコメントで指摘していただいた結果と異なる結果が得られました。
そこで、Mac OS X 10.5〜10.8の各環境で、write命令に「オプションなし」「as Unicode textを指定」「as «class ut16»を指定」「as «class utf8»を指定」の4パターンを試して比較してみました。
すると……
のように、シフトJIS(無指定時)、UTF-16BE、UTF-16LE(BOMつき)、UTF8の結果が得られたものの、最新のOS X 10.8のみその結果が異なる、という結果が出ました。
write命令で、オプションなしかUTF8で書き込むことが多いのですが、なかなか興味深い結果です。10.8の変更が「仕様(意図してのもの)」と見るか、「バグ(意図していなかった)」と見るかは難しいところですが、無指定かあるいはUTF8を使うのが安全なように思えます。
ちなみに、本調査の確認は実際にwrite命令でファイルに同じ文字列「あいうえお」の書き込みを行い、Terminal.app上からhexdumpコマンドで書き込んだファイルの内容を16進ダンプすることで行いました。10.5〜10.8すべてIntel Macで動作確認を行っています。
以下に掲載する各プログラムの実行結果は、OS X 10.8.2上のものです。
スクリプト名:ファイル書き込み(無指定時→MacJapanese or SJIS、言語環境依存) |
–書き込み先のパスを指定 set aTargFile to choose file name set aStr to “あいうえお” –環境依存(日本語環境ではShift_JISだかMacJapanese?、英語だとASCII) write_to_file(aStr, aTargFile, false) of me –> 0000000 82 a0 82 a2 82 a4 82 a6 82 a8 –ファイルの追記ルーチン「write_to_file」 –追記データ、追記対象ファイル、boolean(trueで追記) on write_to_file(this_data, target_file, append_data) try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end write_to_file |
スクリプト名:ファイル書き込み(as string指定時→MacJapanese or SJIS、言語環境依存) |
–書き込み先のパスを指定 set aTargFile to choose file name set aStr to “あいうえお” –環境依存(日本語環境ではShift_JISだかMacJapanese?、英語だとASCII) write_to_file(aStr, aTargFile, false) of me –> 0000000 82 a0 82 a2 82 a4 82 a6 82 a8 –ファイルの追記ルーチン「write_to_file」 –追記データ、追記対象ファイル、boolean(trueで追記) on write_to_file(this_data, target_file, append_data) try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data as string to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end write_to_file |
スクリプト名:ファイル書き込み(as Unicode text指定時→UTF-16LE(BOM付き) |
–書き込み先のパスを指定 set aTargFile to choose file name set aStr to “あいうえお” –UTF-16LE(BOM付き) write_to_file(aStr, aTargFile, false) of me –> 0000000 ff fe 42 30 44 30 46 30 48 30 4a 30 –ファイルの追記ルーチン「write_to_file」 –追記データ、追記対象ファイル、boolean(trueで追記) on write_to_file(this_data, target_file, append_data) try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data as Unicode text to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end write_to_file |
スクリプト名:ファイル書き込み(as «class ut16»指定時→UTF-16BE |
–書き込み先のパスを指定 set aTargFile to choose file name set aStr to “あいうえお” –UTF-16BE write_to_file(aStr, aTargFile, false) of me –> 0000000 30 42 30 44 30 46 30 48 30 4a –ファイルの追記ルーチン「write_to_file」 –追記データ、追記対象ファイル、boolean(trueで追記) on write_to_file(this_data, target_file, append_data) try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data as «class ut16» to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end write_to_file |
スクリプト名:ファイル書き込み(as «class utf8»指定時→UTF-8) |
–書き込み先のパスを指定 set aTargFile to choose file name set aStr to “あいうえお” –UTF-8 write_to_file(aStr, aTargFile, false) of me –> 0000000 e3 81 82 e3 81 84 e3 81 86 e3 81 88 e3 81 8a –ファイルの追記ルーチン「write_to_file」 –追記データ、追記対象ファイル、boolean(trueで追記) on write_to_file(this_data, target_file, append_data) try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data as «class utf8» to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end write_to_file |
12月 12th, 2012 at 18:22:02
バグだったもよう……………。
12月 31st, 2012 at 3:20:45
コメントした本人も忘れていました;
元々の確認環境は10.5~10.7だったと思います
当時まだ10.8は使っていませんでしたので
でもって10.8で確認してみたのですが…おや、逆になってない?
こちらの環境では10.7までと同じ結果になるご様子
念のため上のサンプルスクリプトをそのまま試してみましたが、結果は変わらず
バグってのはそういう意味なのでしょうか?
12月 31st, 2012 at 7:23:36
そういう意味です。10.8.3betaでは直っているようです。