node-ftpのインストール
これがないと始まらない
node-ftp
npm install ftp
※使用バージョン
- node-ftp : 0.3.10
- node : 0.12.7
問題のコード
let ftp = new require('ftp')() ;
// -- 中略 --
ftp.put('input/path/file.txt','dstpath.txt',function(err){}) ;
これで'input/path/file.txt'が
- 存在する場合
- リモート側にふつーに'dstpath.txt'ファイルが作成される。
- 存在しない場合
- リモート側に中身が'input/path/file.txt'の'dstpath.txt'ファイルが作成される。
node-ftpのReadmeに
put(< mixed >input, < string >destPath, [< boolean >useCompression, ]< function >callback)
-- 中略 --
input can be a ReadableStream, a Buffer, or a path to a local file.
こう書いてあるからstringに対応するpathが存在しなかったらエラーにして欲しいのだが…
なんでこうなるか?
node-ftpのconnection.jsの中身のぞいてみると、
第一引数(input)がstringのとき、statでファイルの存在を確認して
- 存在する場合
- ファイルのReadStream作成
- 存在しない場合
- stringそのまま送信
どうするか?
- とりあえずReadableStreamにして渡してみる
if( typeof input == 'string' ) input=fs.createReadStream(input) ;
ファイルが存在しなくても、この時点ではエラーが出ない。
読み込み時(ftp.put()の中)で例外が発生して
throw er; // Unhandled 'error' event
これが出てprocess終了。
どうやらエラーハンドリングしてくれていないらしい… - putの前にinputのReadableStreamの'error'イベントのハンドリングを追加
input.on('error',function(err){/* エラー処理 */});
ftp.put('input/path/file.txt','dstpath.txt',function(err){}) ;
エラー処理は出来るようになったけど、ftp.logout()で終了しない。
6分ほどたってから 正常 終了した。 - 終了処理はReadmeのサンプルではend()で終わる様にかいてるから、それに従う。
結果
実際にはPromiseでくるんだりして、ゴニョゴニョしてるんだけど、だいたいこんな流れ。
let input = 'input/path/file.txt' ;
let ftp = new require('ftp')() ;
ftp.on('ready',function(){
if( typeof input == 'string' ) { // 文字のときはReadableStreamに置き換え
input=fs.createReadStream(input) ;
input.on('error',function(err){
// ファイル読み込みのエラー処理
}) ;
}
ftp.put(input,'dstpath.txt',function(err){
// ftp.logout(function(err){}) ; // end()に変更
ftp.end() ;
}) ;
}) ;
ftp.connect(/* {FTPパラメータ} */);