@kumatch
Feedtailor inc.
ObjectiveCを使って開発するのが中心だが、
サーバー側の担当
video game fun
通常のwebだと敢えてnodeを使う必要がないのが難点
Agenda
- Summary
- Usage
- Case Study
- Stream classes
Stream Summary
nodeの中のIOを抽象化したインターフェイスのこと
data streamを操作する操作のことをストリームという
docmentを見ると、すぐにstreamの記述場所が分かる
readable / writable stream
データの流れを表現するオブジェクトなので、
読み込み用と書き出し用のストリームが存在する。
How to copy files on Node
Node上でファイルをコピーするとき、どうしたらよいのか?
ファイルのモジュールにコピーのための機能があったりするが、
nodeではfileにアクセスするためのfsモジュールがある。
fsモジュールを利用してファイルを読み込み、自分でファイルをコピーする必
要がある。
var fs = require('fs); var input = './original.jpg'; var output = './copy.jpg'; var data = fs.readFileSync(input); fs.writeFileSync(output, data); console.log('copied');
読み込みと書き出しが同期的に行われる。
処理中は他に何もできない。また、データの量も分からない。
nodeでは非同期で処理を行う必要になる。
var fs = require('fs); var input = './original.jpg'; var output = './copy.jpg'; fs.readFile(input, function (err, data) { if(err) throw err; fs.writeFile(output, data, function(err) { if (err) throw err; console.log('copied'); }); });
streamを使ってインターフェイスを利用する。
var fs = require('fs'); var readStream = fs.createReadStream('./original.jpg); var writeStream = fs.createWriteStream('./copy.jpg'); readStream.pipe(writeStream); writeStream.on('close', function() { console.log('copied'); });
Stream Usage
Stream is EventEmitter and has some methods.
ストリームオブジェクトはイベントエミッターである。
読み込みのためのメソッドと、書き込みのためのメソッドが存在する。
コピー元のファイルをストリームで読みこむ
readable stream
Methods
- resume 読み込む処理を再開する
- pause 読み込む処理を一旦停止する
- destory 読み込む処理を停止する
Events
- data データを読み込む
- and 最後まで終わった場合発生する
- close クローズ処理
- error エラーが発生したとき
writable stream
Methods
- write データを書き込む
- end 書き込み処理を終了させる
- destroy 書き込み処理を停止する
Events
drain writable streamの処理の準備が出来たときに発生する(IOが遅いときは、falseを返しdrainが失敗する)
close 書き込み処理を閉じるときに発生する
error エラーが発生したときに発生するイベント
var fs = require('fs'); var readStream = fs.createReadStream('./original.jpg'); var writeStream = fs.createWriteStream('./copy.jpg'); readStream.resume(); // 書き込み続ける readStream.on('data',function (buffer) { writeStream.write(buffer); }); // 読み込み終了 readStream.on('end',function(){ writeStream.end(); }); // 書き込み終了(これが発生しないと、書き込みが終わらない) writeStream.on('close', function() { console.log('copied'); });
Stream pipe()の機能について
Source stream(readable) pipe→ Destination stream(writable)
パイプを使って、読み込み側から書き込み側へデータを流す
pipeの処理内容は、以下3つを中心にして処理を続ける
書く
destination.write() if source on 'data'.
停止
source.pause() if destination buffer is full. 処理が間に合わないとかで
現在書き込み不能な場合
読み込み処理再開
source.resume() if destination on 'drain' 処理の準備が完了したとき
pipeのオプション
[optional]
Keeps the destination stream open.
書き込みが完了したら、closeにするが、
書き込み終了してもcloseしない。
(例: 複数のreadableストリームと一つの宛先が存在するとき、
一つの読み込み処理が終了してもcloseしない)
var fs = require('fs'); var readStream = fs.createReadStream('./original.jpg'); var writeStream = fs.createWriteStream('./copy.jpg'); readStream.pipe(writeStream); // 書き込み終了(これが発生しないと、書き込みが終わらない) writeStream.on('close', function() { console.log('copied'); });
読み込みが満杯ならストップし、準備が出来たら再開…を繰り返す。
Case Study 2
Digest SHA1 has of a file
これをnodeでやる場合は、やっぱりstreamを使う
var crypto = require('crypto'); var fs = require('fs'); var filename = process.argv[2]; var hash = crypto.createHash('sha1'); var stream = fs.ReadStream(filename); // ハッシュをアップデート stream.on('data', function(buffer) { hash.update(buffer); }); // ハッシュからダイジェストへデータを渡しまくり、 // 結果(ハッシュ値計算)を出力する stream.on('end', function() { var digest = hash.digest('hex'); console.log(digest); });
streamを使って、読み込んだデータをひたすら
hash計算し、コンソールに出力する
stream classes
処理の詳しい中身はそんなに知らなくてもいい
(ただエラーとかは把握すること)
- Filesystem (fs)
- readStream (読み込み用)
- writeStream (書き込み用)
- Net
- net.Socket (読み込み用/書き込み用 どちらでも可)
与えられたデータが読み込み用でも書き込み用でもありうるときでも
対応できる
- HTTP
- http.ServerRequest (Readable)
- http.ServerResponse (Writable)
サーバーが何かしら返す場合
リクエストはreadable
レスポンスはwritable
- Zlib(圧縮・解凍系)
- all classes (Readable/Writable)
- Gzip/Gunzip
- Deflate/Inflate
- DeflateRaw/InflateRaw
- all classes (Readable/Writable)
ファイルを読み込み、gzipに圧縮して、圧縮したものを
レスポンスに書き出す、というストリームの実装も可能になる。
- fs.Readable
- pipe
- zlib.Gzip
- pipe
- http.response
streamを制する者はnodeを制す
References
- Node manual & documentation
- by Jxck
- jxckさんのはてな http://d.hatena.jp/jxck/20111204
- A future in stream / Streams2(Github issue)
メソッドチェインでstreamもどんどんできるよ。
マニュアルもあるから見てください。