AEスクリプトでバイナリファイル - [[レンダー乙女とか]]
どうも、読み書きできそうです。
スクリプティングガイドには、あまりはっきり書いていないし、 サンプル等にもないので「できない?」とか漠然と思っていましたが…
ガイドをよーく見るとFileオブジェクトのencoding に"BINARY"とかあったりするのです。
さらにその近所には
The ASCII encoder raises errors for characters greater than 127, and the BINARY encoder simply converts between bytes and Unicode characters by using the lower 8 bits. This encoder is convenient for reading and writing binary data.
ASCIIエンコーダは、127より大きな文字のにはエラーをだします。 また、BINARYエンコーダは下位8ビットを使用するUnicode文字とバイト間を単に変換します。 このエンコーダはバイナリデータの読み書きに便利です。
??みたいなことが書いてある。
あれれ? できるのかね?
で、チョト試してみました。
/* * binary-file I/O TEST * * 2006/05/14 Nekomataya * バイナリファイルの I/O 試験です * スクリプティングガイドによるとファイルを開いて、バイト単位でシーク可能なので * 取り込み可能なのでは無いかと思って試験してみました。大丈夫そう… * charCodeAt()/ fromCharCode() メソッドは、Latin-1規定外のコード(x00-x1F,x80-x9F)でも * 問題なく読み書きできる様です。 * とりあえず、 * -ファイルを配列に数値で取り込むメソッド * -ファイルに配列を書き込むメソッド * このふたつを作ってみました。(ああ、でも6.5では意図した通りに動かん) * 6.5ではread(1)が勝手に2バイト読んでいる模様 - ケース確認が必要…調整したぞ 5/24 */ /* ファイルを開いて内容を配列に取り込む * getBin([ファイル]) * 引数 :ファイルオブジェクト * 戻り値 :ファイル内容 1バイト/1要素 の配列 */ getBin=function(myFile) { if ((!myFile)||(! myFile.exists)){alert("ファイルがないみたいです。");return false;} var myOpenfile = new File(myFile.fsName); myOpenfile.encoding="BINARY"; var myContent=new Array(); myOpenfile.open("r"); if(app.buildName.match(/^6?.5/)) { for (var readAddress=0;readAddress<myOpenfile.length;readAddress++) { myOpenfile.seek(readAddress,0); var biteData=myOpenfile.read(1).charCodeAt(0); var btCount=myOpenfile.tell()-readAddress; if(btCount>2){alert(btCount+" : "+biteData);} for(ct=btCount;ct>0;ct--) { myContent.push(Math.floor(biteData/Math.pow(256,ct-1))%256);//上位バイトから順にプッシュ } readAddress=readAddress+(btCount-1); } /* * AE65用処理パターン どうもUTF-8読み込み固定っぽい シークは正常 * 何バイト読んだか判定してシークを進める仕様に変更!これか? * 読出しが何バイトか取得 読出しアドレスとシーク位置の差分を取る事にする。よさげ?バージョン分岐不要かも。 */ }else{ for (var readAddress=0;readAddress<myOpenfile.length;readAddress++) { myOpenfile.seek(readAddress,0); biteData=myOpenfile.read(1).charCodeAt(0); myContent.push(biteData); } } myOpenfile.close(); return myContent; } /* ファイルに配列の内容を書き込む * putBin([ファイル],[配列]) * 引数 :ファイルオブジェクト,配列 * 戻り値 :書き込みに成功すれば、書き込んだファイルオブジェクト * :失敗した場合は、エラー文字列 * 書き込む配列は、読み出しと同形式の アドレス順で 1bite/1要素 の配列 * 配列要素が数値外 または、配列要素<0 だった場合は、0 * 255>配列要素 の場合は、255を書き込みます。 */ putBin=function(myFile,myContent) { if((!myFile) ||(! myContent) ||(! myContent instanceof Array))return false; var myOpenfile = new File(myFile.fsName); myOpenfile.encoding="BINARY"; myOpenfile.lineFeed="unix"; var writeData=0;//書き込みデータバッファ try{ myOpenfile.open("w"); for (var readAddress=0;readAddress<myContent.length;readAddress++) { if(isNaN(myContent[readAddress]) || myContent[readAddress]<0) { writeData=0; }else{ if(myContent[readAddress]>255){ writeData=255; }else{ writeData=myContent[readAddress]; } } myOpenfile.write(String.fromCharCode(writeData)); } myOpenfile.close(); }catch(er){return er;}; return myFile; }; //動作試験 var writeTest=false;//書き込み試験あり? if (system.osName=="MacOS") { var targetFileName=fileGetDialog("test-File","");//mac用 }else{ var targetFileName=fileGetDialog("test-File","*.*");//win用 } if(writeTest){ var writeBody=new Array();//書き込みデータ作成 1bite整数(もどき) for (i=0 ; i<256; i++) writeBody.push(i);//0-255 : データ256ヶ作る var writeFile=new File(targetFileName);//試験ファイルオブジェクト作る var readFile =putBin(writeFile,writeBody); //ターゲットファイルに書き込み 関数の戻り値は書き込んだファイル } if(! writeTest) var readFile =new File(targetFileName); if(readFile) readoutArray=getBin(readFile);//読み出し! //どうよ? alert(readoutArray.toSource()); //
こんなコード
これでもって
サイズ 256バイトのファイルができて
読み出しデータがこんなふうになっていれば…
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255]
それで、バイト単位の読み書きが出来るってことなわけデー…
出来ました
ただし、AE7だけ
ガイドの記述はAE6.5と7.0で同じ内容なのですが、6.5で実行すると…
どうやら勝手にエンコーディングきめ込みで読み書きしてるみたい…
さらに、まだMacでは試験してないです。でもなんだか行けそう? 読み書きできると、やれることが増えてうれしいなぁ…
続報を待て!
では続き
MacOSXでも状況はWindowsと同様でした。
つまり、
6.5ではダメだけど、7.0なら問題なくバイナリファイルが扱える
ってことですね。
ただし、テキストベースにオブジェクト周りが整備されているのでお世辞にも「使い勝手が良い」わけじゃ有りません。
うーむ、どうしようか?幾つか基本的な機能を付けたライブラリを書いたほうが良いな…
- ビッグエンディアンとリトルエンディアンの変換
- バイト数とアドレス指定して数値を取りだす
- バイト数とアドレス指定して文字列を取りだす。
こんなカンジで機能モジュールを整備するで、必要に応じて対応データ毎のプロクシになるクラスを書く…と そんなもんか
ちょっとできる事が増えちゃった わーいわーい
もしも6.5でうまく読み書きできた人がいたら教えて下さいね
何となくリザルトを見ていたら、AE6.5は、2バイトづつ読み込みしているような気がしたので、 バージョンを読んで6.5の時は2バイトづつ読み込む仕様に改造…(前出のソースをアップデート)
お、いけるか?
とかおもったら、状況によっては3バイト読んでいる雰囲気も(UTF-8決め込みっぽい)
ああ、でもUTF-8決め込みならソレハそれで判定して相当データを分離してやるだけでいけそう…
06-05/23
うーん、6.5 書き込みはできないが読み込みは行けるかもってコトで 以下次号(いつかは知らない)
いつかわからんとか言いながら、シーク位置を取得するメソッドがあったのをすぐさま思い出したので そちらで書き換えてみました。…大丈夫そうなのです。
UTF-8 は、1〜6バイトの可変長コードなので追っかけるのが大変とか思っていましたが 本来の問題は、「AEが何バイト読んだかどうか」なので、シーク位置を追いかければ解決です。
上のコードで今のところは 正常に読み書きできているっぽいです。
これにて本件終了!!(かな? まだなにかありそうな気もする…うはほはほ)
Powered by YukiWiki 2.1.2a / Modified by Nekomataya.