Archive for 7月, 2009
AIRでzipファイルの圧縮と展開(解凍)できるライブラリを公開します。
使い方
読み込み方法
import com.coltware.commons.zip.ZipEntry;
import com.coltware.commons.zip.ZipEvent;
import com.coltware.commons.zip.ZipFileReader;
private function unzip(file:File):void{
var zipReader:ZipFileReader = new ZipFileReader();
zipReader.open(file); <- Fileオブジェクトを設定してください
var entries:Array = zipReader.getEntries();
for(var i:int = 0; i<entries.length; i++){
var entry:ZipEntry = entries[i] as ZipEntry;
var filename:String = entry.getFilename();
var bytes:ByteArray = zipReader.unzip(entry);
// ここで、ByteArrayのデータをファイル等に書き出してください。
// getFilename() は、文字コードを自動的にSJISもしくはUTF-8を判別します。
// MACの濁点も解決します。
// ただし、展開処理で bytearray.uncompress(...) を使っているだけなので、なぜか解凍が失敗するものもあります。
}
ってのがおおよその、展開方法です。
zipReader.addEventListener(ZipEvent.ZIP_DATA_UNCOMPRESS,uncompressData); zipReader.unzipAsync(entry);
とすれば、非同期で展開が行われます。
private function uncompressData(e:ZipEvent):void{
var entry:ZipEntry = e.entry;
var file:File = dir.resolvePath(entry.getFilename());
var fs:FileStream = new FileStream();
fs.open(file,FileMode.WRITE);
fs.writeBytes(e.data);
fs.close();
}
のようにしてZipEntryとdata(ByteArray)で操作が行えます。
次回は、書き込みの方法も紹介します。
いま、ソースにコメントを書き込み中・・・・
asdocもできたらドキュメントともにソースも公開したいと思います。
前回、zipファイルの解凍アプリを作ったが、これを環境を移動したときに動くのかチェックをしたいと思ったが、
インストールせずに動作を確認できないだろうか?
とふと思った。
まあ、ほんとにデバッグ的な使い方なのです。
Adobe AIRのSDKではADL(AIR Debug Launcher)というツールが付いているのでこれで実行してみる。
1) まず、xxxxx.airを解凍する。(zipで圧縮されているので解凍ソフトが拡張子で判断する時には.airに変更する。
ちなみに私が作ったzip解凍は拡張子ではなく、ファイルの中身をみるので拡張子を変えなくてもOKなのです。
2) META-INF/AIR/application.xmlがあるので、これを解凍したフォルダ直下に移動(コピー)する。
ここには、実際のswfファイルがあります。
3) 以下のコマンドを実行する
adl.exe application.xml
と、これでOKのはずです。
注意)2009/8/6現在は、バージョンアップしております。
新しいバージョンはこちらからどうぞ。
Zipの解凍方法もほぼほぼわかったので、Zip解凍AIRアプリを作ってみました。
Adobeさんに載っていたZIPファイルの読み方をサンプルに、いろいろとそれから勉強してみました。
それで、ZIPファイルはファイルの後ろから読むんですね。
このおかげで、非同期読み込みで処理をして固まらないようにしたかったのですが、
できず、setTimeout関数を使って解凍処理はバックグラウンドで処理をしています。
ファイル名のSJISとUTF-8は自動的に判断しています。(Macの濁点などの問題も一応解決しています。)
現在の制約は・・・・
パスワード付きZipは解凍できません。
また、解凍もzipファイルのあるフォルダにしか解凍できません。
こちらからどうぞ
ちなみに確認した環境はWindows Vistaです。
今後、部分解凍(選択したファイルのみ)とか、エラー処理とか・・・・ いろいろやっていきたいと思います。
Flex Builderとsubversion(subclipse)を一緒に使っていて、コミットするとたまに、
「ワークスペースをビルド中」というメッセージで固まってしまうときがある。
なぜだか原因がわからない。そこで、いろいろ試してみる。
1)強制終了&再起動
2)起動時にキャッシュをクリアするようにする。 ( eclipse.exe -clean )
3).metadata\.plugins\org.tigris.subversion.subclipse.coreにある .svnProviderState を削除
4)ワークスペースを再作成
意味があるのかないのかよくわからないが経験則で1から3のようなことをしている。
ほかにもがちゃがちゃとやっているので、それらが影響しているかわからないが、これらで解決してきた。
4)をやれば100%解決できるが、これだとコミットしていないファイルがあると面倒である。
今日の収穫は3)の方法が追加できたことだ。
ライブラリプログラムや、サンプルプログラムと、アプリケーションを作成するためのワークスペースを分けていると、
たびたびワークスペースの切り替えをする必要が出てくる。
これがいちいち面倒だ。起動時に分けて立ち上げたい。
FlexBuilderはしょせん Eclipseだ。
Eclispeの起動オプションを使って起動時にワークスペースを指定して起動しよう。
そうすれば、異なるワークスペースが起動時に指定できる。
設定方法: Windowsの場合)
1.Flex Builder3のプログラムからまずショートカットを作成する。
2.リンク先の最後に -data [ワークスペースのパス]
例)
“C:Program FilesAdobeFlex Builder 3FlexBuilder.exe” -data F:flex
とこんな感じだ。
これをワークスペースごとの作成すればいい。
自作したイベントをFlex Builderで開発しているときにコードアシスト(設定できる対象がでてくるやつ)できるようにしたい場合のメモ。
こんな感じに、設定できるイベントの一覧が出てくれば、楽になる。
そのためには、メタデータタグを書く必要がある。
たとえば、こんな感じ。
[AS]
[Event(name="smtpConnectionFailed",type="com.coltware.fxmail.smtp.SMTPEvent")]
public class SMTPClient extends SocketJobSync
{
// 途中省略
}
[/AS]
ってな具合に記述すれば、コードアシストがきくようになります。
でも、ここで注意!!
の部分を SMTP_CONNECTION_FAILED に変換します。
したがって、実際の変数名もそのようにしなければいけないというわけです。
じゃないと、せっかくコードアシストしても、その結果がコンパイルエラーになってしまうというわけです。
この記事を書いていて初めて気がつきました。
あれ!?、図で出てるアシスト部分と正常な記述が違う!?って。
この辺り、どこかマニュアルに書いてあるのかも知れませんが、私には見つかりませんでした。
でもって、asdocに記述されるようにするには、
[AS]
/**
* SMTPレベルで接続ができなかったときのイベント.
*
* メモ:Socketベースではありません。HELOもしくはEHLOを投げてエラーとなったときに発行されます
* ただし、EHLOでESMTPをサポートしていないエラーはここに含まれません。
*
* @eventType com.coltware.fxmail.smtp.SMTPEvent.SMTP_CONNECTION_FAILED
*/
[/AS]
ってな具合に、@eventTypeを記述すればOKだ。
しかし、メタタグのところでイベントの文字列を、asdocのところで変数名をと、
結構、コード部分以外にも意味が入ってしまうので、いろいろなところで整合性をきちんと持たせようと思うと、結構つらい部分がある。
Postfix とdovecotを使ってSMTP AUTHを使えるようにする必要性が出てきた。
というのも、gmailではSMTP AUTHが必須になっているので、このテストのためにもこの設定が必要だ。
このSMTP AUTHの問題さえ解決できれば私が作っているAdobe AIR版SMTPライブラリでメールがGmailを使って送れるようになる。
すでに、POP3版もできているので、これがそろえば送受信が行える。
幸いにも認証方法はLOGIN PLAINになっているので、dovecotで十分だ。
ちなみに、Postfixとdovecotのインストールがされていることが前提なので注意。
さて、PostfixでSMTP AUTHを使えるようにするにはというのをさがしてみるとPostfixの再インストールがされているものばかり。
しかし、最近インストールしたものなので、再インストールは必要ないだろうということで、それを確認する。
#postconf -a cyrus dovecot
SMTPの認証にcyrusというのとdovecotが使えると出力されているので、問題なくdovecotが使えるのが確認できた。
このあたりの確認方法は
man postconf
と打てば使いかたは出てくる。
-a List the available SASL server plug-in types. The SASL plug-in type is selected with the smtpd_sasl_type configuration parameter by specifying one of the names listed below. cyrus This server plug-in is available when Postfix is built with Cyrus SASL sup- port. dovecot This server plug-in requires the Dovecot authentication server. This feature is available with Postfix 2.3 and later.
と出てきたので、Version が2.3より新しければだいたい大丈夫なのかもしれない。
また、postconfはこれから設定ファイルを変更するのだが、その設定がきちんと設定されているかなどを確認するのにも使う。
(私自身、スペルを間違ってしまってはまってしまったなんて時に、これを使って再確認する。)
さて、Postfixとdovecotの設定を行う。
詳しい設定は、http://www.postfix.org/SASL_README.html#build_dovecotにあるので、こちらを見てほしい。
しかし、ここではプログラム確認のためのサーバなのでセキュリティやら何やらの設定はいらない。
できるだけ、何の制約もなく使えるようにしたいので、必要最低限の設定を行う。
なので、実際の運用に使うものの設定ではないので、ご注意頂きたい。
/etc/postfix/main.cf 以下を追加
smtpd_sasl_auth_enable = yes smtpd_sasl_authenticated_header = yes broken_sasl_auth_clients = yes smtpd_sasl_type = dovecot smtpd_sasl_path = private/auth
/<どこかのパス>/dovecot.conf
以下のような記述が既にあるので、下記を参考に変更、もしくは頭の#を取って設定を有効にする。
auth default {
mechanisms = plain login
:
途中省略
:
socket listen {
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}
これで、postfixとdovecotを再起動すれば問題ない。
ちなみに、テストで
$telnet localhsot 25 <-- (入力) 220 localhost ESMTP Postfix EHLO localhost <-- (入力) 250-PIPELINING 250-SIZE 10240000 250-VRFY 250-ETRN 250-AUTH PLAIN 250-AUTH=PLAIN 250-ENHANCEDSTATUSCODES 250-8BITMIME 250 DSN AUTH LOGIN <-- (入力) 334 VXNlcm5hbWU6 xxxxxxxxxx <-- (入力)ここにLogin Userをbase64した形で入力 334 UGFzc3dvcmQ6 yyyyyyyyyy <-- (入力)ここにPasswordをbase64した形で入力 235 2.0.0 Authentication successful QUIT <-- (入力) 221 2.0.0 Bye
ちなみに、
334 VXNlcm5hbWU6
などのように出力されるが、
これは、
334 Username:
と出力されている。VX..の部分がBASE64でエンコードされているだけだ。
また、UGFzc3dvcmQ6は「Password:」と出力されている。
このあたりが、BASE64でどうせセキュリティがほとんどないのに、このようになっている意味はよくわからない。
前回、Zipファイルの読み込みの実装方法を書いたわけだが、そもそも私が求めていたドキュメントがAdobeのサイトにあった。
しかし、これはよいのだ。もう別に見なくても分かっている。
前にも書いたが、AIRでZIPファイルを読めたらなとおもった理由が2つ。
1つ目: オフィスドキュメント(XML形式をZIPで固めたもの)を読むこと
これは、実装できてもまだ使えるような具体的なものが浮かばないので、さきがながーいものになる。
2つ目: WindowsでMACのzipファイルを解凍できること。
これがすぐにでもほしい。MACのファイルを解凍すると必ず意味のわからない文字化けがする。
Windowsがファイル名がSJISで、MacがUTF-8だから簡単にできそうだ・・・と思った。
しかし、ここで断念。
濁点の文字化けが解決できない・・・・
たとえば、データが テ?ータになってしまう。
んー、MACでは、デは「テ」+「゛」らしい。
しかも、ファイルシステムだけ・・・・
こんなの知らんよ。MACなんてつかわんし。
結局、調べたらMACのUTF-8形式らしい。
面倒すぎて解決するのを一時やめました。
Arrayからデータを消すには、ちょっと癖がある。
とくに、shiftやpopなどのように先頭や最後からデータを消そうとすると、
ちょっとプログラムをしている手がとまる。
ということで、覚書のために載せておく。
これ以外にも方法はあるとは思います。
1.指定したオブジェクトのデータを削除する
[AS]
// 削除したいオブジェクトの場所を見つける
var index:int = mx.utils.ArrayUtil.getItemIndex(findMe,arrayObject);
// その場所から1つのオブジェクトを消す
arrayObject.splice(index,1);
[/AS]
2.すべてのデータを削除する
[AS]
arrayObject.length = 0;
[/AS]
lengthを0にすればすべてのデータを削除できるなんて、
メモ : length プロパティに既存の長さよりも短い値を割り当てた場合、配列は切り詰められます。
なんてメモからは思い浮かびませんよね。
Flexでは、Base64方式にエンコードも、デコードも簡単にすることができます。
とくに、デコードなどはネットから取ってきたBase64形式で取得して、画像として表示(バイナリ形式にもどす)ということもやることでしょう。
では最初は、デコード方式
[AS]
import mx.utils.*;
var base64strings:String = “GyRCJDMkbCRPJUYlOSVIGyhC”;
var decorder:Base64Decoder = new Base64Decoder();
decorder.decode(base64strings);
var bytes:ByteArray = decorder.toByteArray();
bytes.position = 0;
// 後はByteArray形式なのでそこからデータを対象の方式で読み込む
[/AS]
非常に簡単なのが分かると思います。
次に、エンコード
[AS]
var bytes:ByteArray = new ByteArray();
var title:String = “Base64する対象の文字列です。”;
// 以下は、文字を
bytes.writeMultiByte(title,”iso-2022-jp”);
var encoder:Base64Encoder = new Base64Encoder();
// 76 文字ごとの改行処理を入れない
// 通常は、default (true) で問題なし。
// 今回はメールの件名の部分のためにfalseを指定
encoder.insertNewLines = false;
encoder.encodeBytes(bytes);
var base64strings = encoder.toString();
[/AS]
ってな感じですね。




