Kasper's Classes
この記事を書いている2002年11月の段階では、Java用に用意された FTP クライアントで、比較的マトモに動いてくれるフリーのものというと、Kasper
さんの作成された Kasper's
Classes 内の Kasper.net.ftp がお勧めです。
1997年7月以来メンテナンスされていないようですので、若干不安はありますが、英語が読める方でしたら、分かりやすいサンプルのついた非常に丁寧なドキュメントがありますので、比較的簡単に使えます。
特に、FTPプロトコルについての知識をお持ちの方でしたら、英語が読めなくても非常に簡単に使えると思います。
ソースコードは有償公開というスタンスを取っておられるため、どうしてもソースがないとダメな人は別ですが、特に不具合が原因でソースを見なければならないということはありませんでした。
Kasper.net.ftp を使用した、具体的なコーディングの例は以下のとおりです。
ftpクライアントクラスのインスタンス生成などの準備
以下のように、FTPClient クラスインスタンスと、FTPServerResponse クラスインスタンスを事前に生成しておきます。
public FTPClient ftpClient = new FTPClient();
public FTPServerResponse ftpResponse = null;
ログインメソッドの例 ftpLoginCwd
面倒なので、私の場合は、機能ごとにメソッドを作っています。
基本的には、FTPClient クラスにFTPコマンドに対応するメソッドが用意されていますので、これを呼び出し、FTPServerResponse型のレスポンスを受信するという流れになります。
このメソッドの引数と、その内容については、以下のとおりです。
|
引数
|
説明
|
| ftpClient |
先に生成した、FTPClient型クラスインスタンス |
| ftpServer |
接続先FTPサーバーのFQDN
例: "ftp.hoge.com" , "ftp.foo.com" ....等 |
| username |
FTPサーバーのログイン名 |
| password |
FTPサーバーのログインパスワード |
| accountInfo |
FTP課金情報
FTPサーバーが要求する場合のみ必要です。
が、ほとんどの場合、""(空白文字列)で構いません。
|
| remoteDir |
ログイン後にFTPのCWDコマンドで移動する移動先ディレクトリのパス
リモートのカレントディレクトリをどこに変更するか。ということです。
例: "/cgi-bin/bulletinboard/logdata" , "/public_html/link" |
例外処理がかなりいいかげんになっています。必要に応じて追加したほうがよいでしょう。
public void ftpLoginCwd(FTPClient ftpClient, String ftpServer, String username,
String password, String accountInfo, String remoteDir) {
try {
// FTPサーバーへの接続
System.out.println( ftpResponse = ftpClient.connect( ftpServer ) );
if ( ftpResponse.getResponseCode() != FTPServerResponse.SERVER_READY ){
System.exit(1);
}
// user コマンド
System.out.println( ftpResponse = ftpClient.user(username) );
// pass コマンド
if ( ftpResponse.getResponseCode() != FTPServerResponse.PASSWORD_NEEDED ){
System.exit(1);
}
System.out.println( ftpResponse = ftpClient.pass(password) );
// acct FTP課金情報が必要か?
if ( ftpResponse.getResponseCode() == FTPServerResponse.ACCOUNT_NEEDED ){
// 必要ならFTP課金情報を送信する。
System.out.println( ftpResponse = ftpClient.acct(accountInfo) );
if ( ftpResponse.getResponseCode() != FTPServerResponse.USER_LOGGED_IN ){
System.exit(1);
}
}
// cwd ディレクトリ変更
System.out.println( ftpResponse = ftpClient.cwd(remoteDir) );
if ( ftpResponse.getResponseCode() != FTPServerResponse.FILE_ACTION_OKAY ){
System.exit(1);
}
}
catch (Exception e){
System.err.println("Exception attempt to connecto to " + ftpServer);
e.printStackTrace(); //スタックトレースの出力
System.exit(1);
}
}
FTPでのファイルアップロードメソッドの例 ftpStoreFile
このメソッドは、ローカルに存在するファイル localFilename を、引数 remoteFilename で指定したファイル名で、FTPサーバーにアップロードします。
このメソッドの引数に渡す ftpClient は、事前にログイン処理を済ませ、カレントディレクトリの移動も済んでいることが必要です。
このメソッドでは、Passiveモードでアップロードを行っています。
JavaからFTP接続するケースは、実際にはファイアーウォール越えになるケースが多いと考えられますので、特に問題がなければ、Activeモードで接続する必要はないと思います。(アプリケーションサーバーの前にファイアーウォールが無いってことはないでしょ?)
下のコードでは、例外処理がいいかげんになっています。必要に応じて追加してご使用ください。
public void ftpStoreFile( FTPClient ftpClient, String localFilename, String remoteFilename){
try {
// pasv コマンド(Passive モードに切り替える)
System.out.println( ftpResponse = ftpClient.pasv() );
if ( ftpResponse.getResponseCode() != FTPServerResponse.ENTERING_PASSIVE_MODE ){
System.exit(1);
}
// stor コマンド / ファイル取得
FTPServerResponse ftpResponses[] = ftpClient.stor(localFilename, remoteFilename);
System.out.println(ftpResponses[0]);
System.out.println(ftpResponses[1]);
if ( ftpResponses[1].getResponseCode() != this.TRANSFER_COMPLETE ){
System.exit(1);
}
}
catch (Exception e){
System.err.println("Exception attempt to connecto to " + ftpServer);
e.printStackTrace(); //スタックトレースの出力
System.exit(1);
}
FTPでのファイルダウンロードメソッドの例 ftpGetFile
このメソッドは、FTPサーバーのカレントディレクトリに存在する remoteFilename をダウンロードし、ローカルマシンに引数
localFilename で指定されたファイル名で保存します。
このメソッドの引数に渡す ftpClient は、事前にログイン処理を済ませ、カレントディレクトリの移動も済んでいることが必要です。
また、このケースでも、前出のアッフロード同様Passiveモードを使用しています。
Passive モードへの切り替えは、データコネクションの作成の度に必要なため、たとえば、1セッションで2回のファイル転送をするのであれば、2回Passiveモードへの切り替えが必要です。
したがって、下記コードのPassiveモード切替は省略できません。
また、ここではサンプルを掲載しませんが、FTPでは、カレントディレクトリのファイルリストの取得の際にも、データコネクションを張りますので、このときもPassiveモード切替が必要でしょう。
下のコードでは、またしても、例外処理がいいかげんになっています。必要に応じて追加してご使用ください。
public void ftpGetFile( FTPClient ftpClient, String remoteFilename, String localFilename ) {
try {
// pasv コマンド(Passive モードに切り替える)
System.out.println( ftpResponse = ftpClient.pasv() );
if ( ftpResponse.getResponseCode() != FTPServerResponse.ENTERING_PASSIVE_MODE ){
System.exit(1);
}
// retr コマンド / ファイル取得
FTPServerResponse ftpResponses[] = ftpClient.retr(remoteFilename, localFilename);
System.out.println(ftpResponses[0]);
System.out.println(ftpResponses[1]);
if ( ftpResponses[1].getResponseCode() != this.TRANSFER_COMPLETE ){
System.exit(1);
}
}
catch (Exception e){
System.err.println("Exception attempt to connecto to " + ftpServer);
e.printStackTrace(); //スタックトレースの出力
System.exit(1);
}
}