研究室生活のメモ・・・だった過去の遺産。移転先→http://negimochix2.blogspot.com/
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
やべぇw忙しさのあまり,今週の分,更新するの忘れるところだった.
アンダーグラウンド・カタログ聴いてたら,とても良さげな曲を発見.
音割れがあるのが残念な点ではあるけど,
それを差し引いてもいい曲.
ychさんの曲をもう1曲.
こっちもいい感じ.
PR
都合上,XMLを自由に読み書きする必要が出てきた.
そこで,FileStreamクラス(AIRで追加されたファイルの読み書き用クラス)を使い,
XMLのメソッド1つで,非同期に読み書きをするXMLManagerクラスを作ってみた.
openメソッドを使うと,それ以降のFileStreamの処理は,その行の処理が終わるまで次の行を実行しない.
でも,それだと,ロード対象のサイズが大きくなった場合などに遅延が起きてしまう.
それを避けたいのなら,openAsyncメソッドでファイルオープンする.
openAsyncにすると,各処理ごとにイベントを発行する.
つまり,FileStreamのオブジェクトにaddEventListenerしとけば,読み込み終わりとか判定できるわけです.
そこで,上記のXMLManagerでは,各イベントを利用してMXLの読み書きを行い,さらにカスタムイベントを配信する.
EventDispatcherを継承したのはこのため.
これ,作るときに気づいたんだが,
READモードだとcompleteイベント発生するのに,WRITEモードではcompleteイベント発生しないんだね.
最初気づかずにWRITEモードでもcompleteでファイルクローズしてたから,
イベント自体が発生してないからクローズされていないってことで,
上書き時にエラー出て散々ハマりましたw
しょうがないんで,OutputProgressイベント(出力中に定期的に発生するイベント)を使って,
bytesPending(残りの書き込みバイト数)がゼロになったときにクローズするようにしてみた.
そこで,FileStreamクラス(AIRで追加されたファイルの読み書き用クラス)を使い,
XMLのメソッド1つで,非同期に読み書きをするXMLManagerクラスを作ってみた.
package { import flash.events.EventDispatcher; import flash.events.OutputProgressEvent; import flash.events.Event; import flash.filesystem.File; import flash.filesystem.FileMode; import flash.filesystem.FileStream; /** XML用クラス * @auther kusamochi * @extend EventDispatcher */ public class XMLManager extends EventDispatcher { public static const READ_COMPLETE:String = "read_complete"; public static const READ_CLOSE:String = "read_close"; public static const WRITE_PROGLESS:String = "write_progress"; public static const WRITE_CLOSE:String = "write_close"; private var _xml:XML; // [read]xmlファイルの実体 private var fileStream:FileStream; private var _mode:String; //コンストラクタ public function XMLManager() { _mode = "NormalMode"; } // 明示的な参照解除メソッド public function deleteReference():void { if(fileStream) { if(_mode == "ReadMode") { fileStream.removeEventListener(Event.COMPLETE, readStreamCompleteHandler); fileStream.removeEventListener(Event.CLOSE, readStreamCloseHandler); } else if(_mode == "WriteMode") { fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeStreamOutputProgressHandler); fileStream.removeEventListener(Event.CLOSE, writeStreamCloseHandler); } } } // ファイル読み込み public function readXML(file:File):void { trace("XMLManager::readXML"); trace("Reading : " + file.nativePath); _mode = "ReadMode"; fileStream = new FileStream(); fileStream.addEventListener(Event.COMPLETE, readStreamCompleteHandler); fileStream.addEventListener(Event.CLOSE, readStreamCloseHandler); fileStream.openAsync(file, FileMode.READ); } // ファイル出力 public function writeXML(file:File):void { trace("XMLManager::writeXML"); trace("Writing : " + file.nativePath); _mode = "WriteMode"; fileStream = new FileStream(); fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeStreamOutputProgressHandler); fileStream.addEventListener(Event.CLOSE, writeStreamCloseHandler); fileStream.openAsync(file, FileMode.WRITE); fileStream.writeMultiByte(_xml.toXMLString(), File.systemCharset); } public function printXML():void { trace(_xml.toXMLString()); } // EventHandler /////////////////////////////////////////////////////////// // Read ---------------------------------------- // Readストリームがクローズ private function readStreamCloseHandler(event:Event):void { trace("XMLManager::readStreamCloseHandler"); fileStream.removeEventListener(Event.COMPLETE, readStreamCompleteHandler); fileStream.removeEventListener(Event.CLOSE, readStreamCloseHandler); _mode = "NormalMode"; // カスタムイベントを配信する super.dispatchEvent(new Event(READ_CLOSE)); } // 読み込み完了 private function readStreamCompleteHandler(event:Event):void { trace("XMLManager::readStreamCompleteHandler"); var tmpStr:String = fileStream.readMultiByte(fileStream.bytesAvailable, File.systemCharset); fileStream.close(); _xml = new XML(tmpStr); // カスタムイベントを配信する dispatchEvent(new Event(READ_COMPLETE)); } // write -------------------------------------- // Writeストリームがクローズ private function writeStreamCloseHandler(event:Event):void { trace("XMLManager::writeStreamCloseHandler"); fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeStreamOutputProgressHandler); fileStream.removeEventListener(Event.CLOSE, writeStreamCloseHandler); _mode = "NormalMode"; // カスタムイベントを配信する super.dispatchEvent(new Event(WRITE_CLOSE)); } // Write進行中 private function writeStreamOutputProgressHandler(event:OutputProgressEvent):void { trace("XMLManager::writeStreamOutputProgressHandler"); if(event.bytesPending == 0){ fileStream.close(); } // カスタムイベントを配信する super.dispatchEvent(new OutputProgressEvent(WRITE_PROGLESS)); } // getter //////////////////////////////////////////////////// // XMLオブジェクトを返す(他のクラスからのアクセスに対応) public function get xml():XML { return _xml; } // mode public function get mode():String { return _mode; } // setter ////////////////////////////////////////////// public function set xml(setXML:XML) { _xml = setXML; } } }FileStreamクラスのファイルオープンには,openメソッド,openAsyncメソッドの2つがある.
openメソッドを使うと,それ以降のFileStreamの処理は,その行の処理が終わるまで次の行を実行しない.
でも,それだと,ロード対象のサイズが大きくなった場合などに遅延が起きてしまう.
それを避けたいのなら,openAsyncメソッドでファイルオープンする.
openAsyncにすると,各処理ごとにイベントを発行する.
つまり,FileStreamのオブジェクトにaddEventListenerしとけば,読み込み終わりとか判定できるわけです.
そこで,上記のXMLManagerでは,各イベントを利用してMXLの読み書きを行い,さらにカスタムイベントを配信する.
EventDispatcherを継承したのはこのため.
これ,作るときに気づいたんだが,
READモードだとcompleteイベント発生するのに,WRITEモードではcompleteイベント発生しないんだね.
最初気づかずにWRITEモードでもcompleteでファイルクローズしてたから,
イベント自体が発生してないからクローズされていないってことで,
上書き時にエラー出て散々ハマりましたw
しょうがないんで,OutputProgressイベント(出力中に定期的に発生するイベント)を使って,
bytesPending(残りの書き込みバイト数)がゼロになったときにクローズするようにしてみた.
Fileクラスは,AIRで追加された,一括したファイル・ディレクトリ管理ができる万能クラス.
便利なのはいいんだけど,セキュリティーエラーにハマっちゃって・・・.
ハマった割にはたいしたこと無かったけど,知らなかったら解決しない問題なのでメモしておく.
静的プロパティFile.applicationDirectoryはアプリケーションのインストール先を指すFileオブジェクト.
さらに,resolvePathメソッドでpd.iniというファイルパスを作成し,ファイルの保存先(oldPlayData)とする.
さらに,File.createTempFileメソッドで一時保存先(newPlayData)を確保.
oldPlayDataから更新内容があった場合,一時保存先に更新内容を記録しておく.
このへんのプログラムは本題でないので省略.
ウインドウを閉じる時,
一時保存先からコピーしてpd.iniに書き込んだのち,一時保存先のファイルを削除する.
これだけのプログラムなのに,何故か最初のtryで「SecurityError: fileWriteResource」
どーなってんのってググってみたら,
どうやら,applicationDirectoryにおいて,ファイルを作成・書き込みすることはセキュリティ上認められていないらしい.
( ´゚д゚`)エー
その抜け道として,コピー前に,
セキュリティエラーから抜けられるとか.
でもそのかわり,
・AIRアプリケーションアンインストール時に自分で作成したファイルは削除されない
・作成したファイルが残っている状態で再インストールしようとするとエラーが発生
引用: applicationDirectory配下のファイルにアクセスする方法 - Fores Labs
あーだめだこれw
素直に,
これだと,applicationStorageDirectoryは,実際のディレクトリ位置がOSによって,
どうやら,このディレクトリはアンインストールと同時に消去されるらしい.
結論:
applicationDirectoryはファイルの書き込みには使用しない
(使うなら読み込み時.事前にパッケージしたswfとか画像データとかを読み込むのに使えばいい)
便利なのはいいんだけど,セキュリティーエラーにハマっちゃって・・・.
ハマった割にはたいしたこと無かったけど,知らなかったら解決しない問題なのでメモしておく.
// 保存先 var oldPlayData:File = (File.applicationDirectory).resolvePath("pd.ini"); // 一時保存先 var newPlayData:File = File.createTempFile(); // どこかでoldPlayDataの内容を読み込み // どこかでoldPlayDataから更新された内容をnewPlayDataに一時的に保存 // 以下,ウインドウを閉じるときに // newPlayDataが存在するか確認 if(newPlayData.exists) { try { // newPlayDataの内容をoldPlayDataにコピー newPlayData.copyTo(oldPlayData, true); } catch(error:Error) { trace(error.message); } try { // newPlayDataを削除 newPlayData.deleteFile(); } catch(error:Error) { trace(error.message); } }以下,プログラムの構成.
静的プロパティFile.applicationDirectoryはアプリケーションのインストール先を指すFileオブジェクト.
さらに,resolvePathメソッドでpd.iniというファイルパスを作成し,ファイルの保存先(oldPlayData)とする.
さらに,File.createTempFileメソッドで一時保存先(newPlayData)を確保.
oldPlayDataから更新内容があった場合,一時保存先に更新内容を記録しておく.
このへんのプログラムは本題でないので省略.
ウインドウを閉じる時,
一時保存先からコピーしてpd.iniに書き込んだのち,一時保存先のファイルを削除する.
これだけのプログラムなのに,何故か最初のtryで「SecurityError: fileWriteResource」
どーなってんのってググってみたら,
どうやら,applicationDirectoryにおいて,ファイルを作成・書き込みすることはセキュリティ上認められていないらしい.
( ´゚д゚`)エー
その抜け道として,コピー前に,
oldPlayData = new File(oldPlayData.nativePath);というように,一度nativePath(絶対パスのString)からFileクラスを再宣言すると,
セキュリティエラーから抜けられるとか.
でもそのかわり,
・AIRアプリケーションアンインストール時に自分で作成したファイルは削除されない
・作成したファイルが残っている状態で再インストールしようとするとエラーが発生
引用: applicationDirectory配下のファイルにアクセスする方法 - Fores Labs
あーだめだこれw
素直に,
// アプリケーションのプライベート記憶領域を指定 var oldPlayDataFile:File = (File. applicationStorageDirectory).resolvePath("pd.ini");とするのが妥当かな.
これだと,applicationStorageDirectoryは,実際のディレクトリ位置がOSによって,
・Windowsの場合 C:\Documents and Settings\[ユーザ名]\Application Data\[AIRアプリID] \Local Store ・Macの場合 HD/Users/[ユーザー名]/Library/Preferences/[AIRアプリID]/Local Store/となるので,上記のresolvePathでpd.iniを指定した場合は,
・Windowsの場合 C:\Documents and Settings\[ユーザ名]\Application Data\[AIRアプリID] \Local Store\pd.ini ・Macの場合 HD/Users/[ユーザー名]/Library/Preferences/[AIRアプリID]/Local Store/pd.iniとなる.
どうやら,このディレクトリはアンインストールと同時に消去されるらしい.
結論:
applicationDirectoryはファイルの書き込みには使用しない
(使うなら読み込み時.事前にパッケージしたswfとか画像データとかを読み込むのに使えばいい)
LABOとLOVEをかけた素敵ソング.
ネタと韻の踏み方が絶妙.
しかも,強調がスゲェ━━━━━━ヽ(゚Д゚)ノ━━━━━━!!!!
PVも非常に良い感じです.
作ったの誰だろ?って思ってたら・・・あー民Pw
この人の曲,大好きだわ.
ん?すでにがくぽとレンの時点で「嫁」曲じゃないって?
いやいや.
がくぽとレンだってオレのよ・・・
アッー!
世の中こんな便利なものがあるということで.
コード表示用のJava Script.
このブログって,みくみくしているわりには,
プログラムソース貼ること多いので,
これあったほうがいいかと思って.
cssファイル,jsファイルをアップロードして,ヘッダーに少しタグ書くだけでできます.
こちらのサイトを参考にさせて頂きました.
Sun Limited Mt. - ブログにコードを表示するときに便利な dp.SyntaxHighlighter
以下,表示確認用テスト.
XMLをpreで
なんと,SyntaxHighlighterでAS3対応版を作ってくれた人が!
yourpalmark - AS3 Syntax Highlighting (with SyntaxHighlighter)
これはありがたい.
早速テスト,サンプルにAIRのNativeWindowの使用例.
・・・あ,コード自体はパブリッシュしてないので,
エラー出るかもね.
なんか,ずいぶん,技術ブログっぽくなっちゃったな・・・つまらん.
・・・実は,この緑のストライプ.
ミクの縞パンをイメージし(ry
はい,自重自重w
(これで,自分のブログらしくなったな)
コード表示用のJava Script.
このブログって,みくみくしているわりには,
プログラムソース貼ること多いので,
これあったほうがいいかと思って.
cssファイル,jsファイルをアップロードして,ヘッダーに少しタグ書くだけでできます.
こちらのサイトを参考にさせて頂きました.
Sun Limited Mt. - ブログにコードを表示するときに便利な dp.SyntaxHighlighter
以下,表示確認用テスト.
XMLをpreで
<?xml version="1.0" encoding="Shift_JIS"?> <vocaloid> <crypton> <engine ver="1"> <loid>KAITO</loid> <loid>MEIKO</loid> </engine> <engine ver="2"> <loid no="01">初音ミク</loid> <loid no="02">鏡音リン</loid> <loid no="02">鏡音レン</loid> <loid no="03">巡音ルカ</loid> </engine> </crypton> <internet> <engine ver="2"> <loid>がくっぽいど</loid> <loid>Megpoid</loid> </engine> </internet> </vocaloid>さらに!
なんと,SyntaxHighlighterでAS3対応版を作ってくれた人が!
yourpalmark - AS3 Syntax Highlighting (with SyntaxHighlighter)
これはありがたい.
早速テスト,サンプルにAIRのNativeWindowの使用例.
・・・あ,コード自体はパブリッシュしてないので,
エラー出るかもね.
package { import flash.events.MouseEvent; import flash.display.NativeWindow; import flash.display.NativeWindowType; import flash.display.NativeWindowInitOptions; import flash.display.NativeWindowSystemChrome; import flash.display.StageScaleMode; import flash.display.StageAlign; import flash.display.Sprite; public class SubWindow extends NativeWindow { var base:Sprite; public function SubWindow(initX:int, initY:int, initTitle:String, initSprite:Sprite) { base = initSprite; var nwOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); nwOptions.type = NativeWindowType.LIGHTWEIGHT; nwOptions.systemChrome = NativeWindowSystemChrome.NONE; nwOptions.transparent = true; nwOptions.minimizable = true; nwOptions.maximizable = false; super(nwOptions); super.x = initX; super.y = initY; super.width = base.width; super.height = base.heihgt; super.title = initTitle; super.stage.scaleMode = StageScaleMode.NO_SCALE; super.stage.align = StageAlign.TOP_LEFT; super.visible = false; base.addEventListener(MouseEvent.MOUSE_DOWN, widnowMouseDownHandler); super.addChild(base); } // ウインドウを閉じる public override function close():void { base.addEventListener(MouseEvent.MOUSE_DOWN, widnowMouseDownHandler); super.addChild(base); super.close(); } // Event Handler ///////////////////////////////////////////////////////// private function widnowMouseDownHandler(event:MouseEvent):void { super.startMove(); } } }
なんか,ずいぶん,技術ブログっぽくなっちゃったな・・・つまらん.
・・・実は,この緑のストライプ.
ミクの縞パンをイメージし(ry
はい,自重自重w
(これで,自分のブログらしくなったな)
Infomation
【中の人】
・くさもち
・ボカロ廃大学院生
・βからのニコ厨
・もちろん非リア充
・ミクZ4 第二期個人スポンサー
【メール】
・negimochi.tabetai(゚Д゚)gmail.com
(゚Д゚)→@
【その他やってるもの】
・くさもち
・ボカロ廃大学院生
・βからのニコ厨
・もちろん非リア充
・ミクZ4 第二期個人スポンサー
【メール】
・negimochi.tabetai(゚Д゚)gmail.com
(゚Д゚)→@
【その他やってるもの】
・Twitter
・これは痛いピアプロ
・過去の遺産smart.fm
【作ったもの】
・製作に参加したDTX GDPメインサイト
で,実際に作ったIRページ
・これは痛いピアプロ
・過去の遺産smart.fm
【作ったもの】
・製作に参加したDTX GDPメインサイト
で,実際に作ったIRページ
カレンダー
10 | 2024/11 | 12 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
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 |
カテゴリー
VOCALOID Ranking Watcher
新曲は常にチェックすべし。
おすすめ記事
jubeat ripples
今更やってみる
最新記事
(05/02)
(01/08)
(11/26)
(11/24)
(11/13)
(11/06)
(11/06)