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パターンを試して比較してみました。

すると……

write_option.png

のように、シフト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

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

3 Responses to “write命令実行時のファイル書き込みテキストエンコーディングが10.8で変更に”

  1. maro Says:

    バグだったもよう……………。

  2. dreiross Says:

    コメントした本人も忘れていました;

    元々の確認環境は10.5~10.7だったと思います
    当時まだ10.8は使っていませんでしたので

    でもって10.8で確認してみたのですが…おや、逆になってない?
    こちらの環境では10.7までと同じ結果になるご様子

    念のため上のサンプルスクリプトをそのまま試してみましたが、結果は変わらず
    バグってのはそういう意味なのでしょうか?

  3. maro Says:

    そういう意味です。10.8.3betaでは直っているようです。

Leave a Reply