Java FTP接続でファイル送信・ファイル受信する方法
JavaでFTP接続でファイル送信・ファイル受信する方法です。
JavaでFTPするためには Apache Commons Net を利用します。
ここでは JavaでFTP接続でファイル送信・ファイル受信する方法 をサンプルソースで紹介します。
Sponsored Links
目次
環境構築
・Apache Commons Net - Download Commons Net
ここでは commons-net-3.3.jar をダウンロードして利用しています。
Mavenプロジェクトの場合はpom.xmlに下記を追加で。
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.3</version> </dependency>
Sponsored Links
FTP送受信サンプルソース
FTP送受信のサンプルソースです。ここでは FtpConfig という Bean と Ftp というクラスを用意しています。説明はサンプルソースの後に記載しています。
FtpConfigクラス
FtpConfigは、FTP定義 Bean です。
package ftp; import java.io.Serializable; /** * <p><strong>FtpConfig</strong>は、FTP定義 Bean です。</p> */ public class FtpConfig implements Serializable { private static final long serialVersionUID = 1L; public String hostName; public int port; public String userName; public String password; public boolean binaryTransfer; public boolean usePassiveMode; public String hostPath; public String localPath; public String encoding; }
Ftpクラス
Ftpは、FTPをおこなうクラスです。
package ftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; /** * <p><strong>Ftp</strong>は、FTPをおこなうクラスです。</p> * <p>利用方法:</p> * <pre> * try { * Ftp ftp = new Ftp("192.168.0.100", 21, "sakaen", "password", false, false, "/home/sakaen", "C:/Temp/", "EUC_JP"); * if ( ftp.connect() ) * ftp.put(); * ftp.disconnect(); * } catch (Exception e) {} * </pre> * <p>ローカル側パスへは C:/Temp/sakaen.txt などのファイル名指定も可能です。</p> * * @author Sakakibara Engineering Office. * @version $Revision: 1.0 $ $Date: 2015.02.01 $ $Description: 新規作成 $ */ public class Ftp { private FtpConfig config; private FTPClient client; private boolean isConnected; /** * コンストラクタ * * @param config FtpConfig */ public Ftp(FtpConfig config) { this.config = config; this.isConnected = false; } /** * コンストラクタ * * @param hostName ホスト名(IPアドレス:127.0.0.1) * @param port ポート番号(21) * @param userName ユーザー * @param password パスワード * @param binaryTransfer バイナリ転送モード(true: Yes, false: No) * @param usePassiveMode パッシブモード(true: Yes, false: No) * @param hostPath ホスト側パス * @param localPath ローカル側パス * @param encoding エンコーディング(SJIS, MS932, EUC_JP など) */ public Ftp(String hostName, int port, String userName, String password, boolean binaryTransfer, boolean usePassiveMode, String hostPath, String localPath, String encoding) { this.config = new FtpConfig(); this.config.hostName = hostName; this.config.port = port; this.config.userName = userName; this.config.password = password; this.config.binaryTransfer = binaryTransfer; this.config.usePassiveMode = usePassiveMode; this.config.hostPath = hostPath; this.config.localPath = localPath; this.config.encoding = encoding; this.isConnected = false; } /** * パラメータチェック * * @return true: 正常, false: 異常 */ private boolean check() { boolean success = true; // ホスト名 if ( isEmpty(this.config.hostName) ) { System.out.println("hostName Parameter Failed"); success = false; } // ポート if ( this.config.port == 0 ) { System.out.println("port Parameter Failed"); success = false; } // ユーザー名 if ( isEmpty(this.config.userName) ) { System.out.println("userName Parameter Failed"); success = false; } // パスワード if ( isEmpty(this.config.password) ) { System.out.println("password Parameter Failed"); success = false; } // ホストパス if ( isEmpty(this.config.hostPath) ) { System.out.println("hostPath Parameter Failed"); success = false; } // ローカルパス if ( isEmpty(this.config.localPath) ) { System.out.println("localPath Parameter Failed"); success = false; } if ( isEmpty(this.config.encoding) ) { System.out.println("encoding Parameter Failed"); success = false; } return success; } /** * 接続 * * @return true: 正常, false: 異常 * @throws Exception */ public boolean connect() throws Exception { boolean success = check(); if ( !success ) return false; this.client = new FTPClient(); System.out.println("connect...."); this.client.setControlEncoding(this.config.encoding); client.connect(this.config.hostName, this.config.port); System.out.println("Connected to Server: " + this.config.hostName + " on " + this.client.getRemotePort()); System.out.println(this.client.getReplyString()); this.client.login(this.config.userName, this.config.password); System.out.println(client.getReplyString()); if ( !FTPReply.isPositiveCompletion(this.client.getReplyCode()) ) { System.out.println("Login Failed"); this.client.disconnect(); return false; } else { this.isConnected = true; } // Binary転送モードの場合 if ( this.config.binaryTransfer ) { this.client.setFileType(FTP.BINARY_FILE_TYPE); System.out.println("Mode binaryTransfer: true"); } // PASVモードの場合 if ( this.config.usePassiveMode ) { this.client.enterLocalPassiveMode(); System.out.println("Mode usePassiveMode: ON"); } else { this.client.enterLocalActiveMode(); System.out.println("Mode usePassiveMode: OFF"); } // ディレクトリ移動 success = this.client.changeWorkingDirectory(this.config.hostPath); if ( !success ) { System.out.println("Server Directory Failed"); this.client.disconnect(); return false; } System.out.println(this.client.getReplyString()); success = FTPReply.isPositiveCompletion(this.client.getReplyCode()); System.out.println("Connection: " + (success ? "OK" : "NG")); System.out.println("-----------------------------------"); return success; } /** * 切断 * * @return true: 正常, false: 異常 * @throws Exception */ public boolean disconnect() throws Exception { if ( this.isConnected ) { client.logout(); System.out.println(client.getReplyString()); if ( client.isConnected() ) client.disconnect(); } return true; } /** * 送信 * * @return true: 正常, false: 異常 * @throws Exception */ public boolean put() throws Exception { boolean success = true; if ( !this.isConnected ) success = connect(); if ( success ) { // ディレクトリ移動 success = this.client.changeWorkingDirectory(this.config.hostPath); if ( !success ) { System.out.println("Server Directory Failed"); this.client.disconnect(); return false; } return putFiles(new File(this.config.localPath), this.config.hostPath + (this.config.hostPath.endsWith("/") ? "" : "/")); } return success; } /** * ファイル送信 * * @param file FTPFile * @param hostPath ホスト側パス * @throws Exception */ private boolean putFiles(File file, String hostPath) throws Exception { boolean success = true; if ( file.isFile() ) { FileInputStream is = null; try { is = new FileInputStream(file); System.out.println("PUT File Name: " + file.getName()); this.client.storeFile(hostPath + file.getName(), is); is.close(); System.out.println("FTP PUT Completed"); } catch ( Exception e ) { System.out.println("FTP PUT Failed: " + file.getName()); System.out.println(e.getMessage()); success = false; } finally { if ( is != null ) is.close(); } } else if ( file.isDirectory() ) { String dirName = hostPath + file.getName() + "/"; System.out.println("Make Directory: " + dirName); // ディレクトリがなければ作る success = this.client.makeDirectory(dirName); if ( success ) { success = this.client.changeWorkingDirectory(dirName); } else { // ディレクトリが作れない場合、移動してみる success = this.client.changeWorkingDirectory(dirName); if ( !success ) { System.out.println("Server Directory Failed: " + dirName); return success; } } System.out.println("-----------------------------------"); File[] files = file.listFiles(); for ( File f : files ) { success = putFiles(f, dirName); if ( !success ) return success; } } else { } return success; } /** * 受信 */ public boolean get() throws Exception { boolean success = true; if ( !this.isConnected ) success = connect(); if ( success ) { // ディレクトリ移動 success = this.client.changeWorkingDirectory(this.config.hostPath); if ( !success ) { System.out.println("Server Directory Failed"); this.client.disconnect(); return false; } String fileNames[] = this.client.listNames(); if ( fileNames != null ) { for ( int i = 0; i < fileNames.length; i++ ) { System.out.println("Get File Name: " + fileNames[i]); } } System.out.println("-----------------------------------"); for (FTPFile f : this.client.listFiles()) { getFiles(f, this.config.localPath); } } return success; } /** * ファイル取得 * * @param file FTPFile * @param localPath ローカル側パス * @throws Exception */ private boolean getFiles(FTPFile file, String localPath) throws Exception { boolean success = true; if ( !file.getName().equals(".")&&!file.getName().equals("..") ) { String currentDir = client.printWorkingDirectory(); if ( file.isFile() ) { String filename = file.getName(); filename = new String(filename.getBytes("MS932"), "UTF-8"); String utf8filename = client.printWorkingDirectory() + (currentDir.endsWith("/") ? "" : "/") + file.getName(); System.out.println("Get File Name: " + filename); System.out.println("Get UTF8 File Name: " + utf8filename); String localPathName = localPath + (localPath.endsWith("/") ? "" : "/") + filename; System.out.println("Local Path Name: " + localPathName); FileOutputStream os = null; try { os = new FileOutputStream(localPathName); client.retrieveFile(utf8filename, os); os.close(); System.out.println("FTP GET Completed"); } catch ( Exception e ) { System.out.println("FTP GET Failed: " + filename); System.out.println(e.getMessage()); success = false; } finally { if ( os != null ) os.close(); } } else if ( file.isDirectory() ) { File localDir = new File(localPath + (localPath.endsWith("/") ? "" : "/") + file.getName()); String path = localPath; if ( !localDir.exists() ) { localDir.mkdirs(); path = localPath + (localPath.endsWith("/") ? "" : "/") + file.getName(); } success = client.doCommand("CWD", client.printWorkingDirectory() + (currentDir.endsWith("/") ? "" : "/") + file.getName()); for (FTPFile f : client.listFiles()) { success = getFiles(f, path); if ( !success ) break; } //client.doCommand("CDUP", ""); } } return success; } /** * 空文字列チェック * * @param value 文字列 * @return null または 空文字列 なら true , それ以外なら false */ public boolean isEmpty(String value) { if ( value == null || value.length() == 0 ) return true; else return false; } /** * ホスト側パスセット * * @param hostPath ホスト側パス */ public void setHostPath(String hostPath) { this.config.hostPath = hostPath; } /** * ローカル側パスセット * * @param localPath ローカル側パス */ public void setLocalPath(String localPath) { this.config.localPath = localPath; } }
サンプルソースの説明
まず FTPClient をインスタンス化し setControlEncoding メソッドにてエンコードを設定します。次に connect メソッドを使って指定サーバーへ接続します。login メソッドを使ってログインすれば、ファイルを送信したり受信したりできます。
ファイルを送信する場合 storeFile メソッドの引数に FileInputStream を指定します。サンプルソースの putFiles メソッドでは、FTPサーバ上に指定ディレクトリがない場合、新規に作成しています。
ファイルを受信する場合 retrieveFile メソッドの引数に ファイル名と FileOutputStream を指定します。サンプルソースの getFiles メソッドでは、ローカル上に指定ディレクトリがない場合、新規に作成しています。
FTPClientの主なメソッド
サンプルソースで使った FTPClient の主なメソッドです。
メソッド | 説明 |
---|---|
setControlEncoding | エンコーディング(SJIS, MS932, EUC_JPなど)を指定します。 |
connect | IPアドレスやコンピュータ名、ポート番号を指定してFTPサーバーへ接続します。 |
login | ユーザー名、パスワードを指定してFTPサーバーへログインします。 |
setFileType | 転送モードを指定します。(BINARY_FILE_TYPE or ASCII_FILE_TYPE) |
enterLocalPassiveMode | PASVモードの場合、メソッドを呼び出します。 |
enterLocalActiveMode | PASVモード以外の場合、メソッドを呼び出します。 |
changeWorkingDirectory | ディレクトリを移動します。 |
logout | ログアウトします。 |
isConnected | FTPサーバーへ接続されているかどうかを判断します。 |
disconnect | FTPサーバーへの接続を切断します。 |
storeFile | FTPサーバーへファイルを送信します。 |
printWorkingDirectory | 現在の作業ディレクトリのパス名を返します。 |
retrieveFile | FTPサーバーからファイルを受信します。 |
doCommand | コマンドを発行し、応答を待ちます。 |
Sponsored Links
FTP送受信テスト
それでは FTP送受信のテストをしてみましょう。テストソースはこんな感じです。
public class FtpTest { public static void main(String[] args) { try { Ftp ftp = new Ftp("192.168.0.100", 21, "sakaen", "password", false, false, "/home/sakaen", "C:/Temp/", "EUC_JP"); if ( ftp.connect() ) { ftp.get(); ftp.setLocalPath("C:/Temp/サカエン"); ftp.put(); ftp.disconnect(); } } catch (Exception e) { System.out.println(e.getMessage()); } } }
Ftp クラスへのパラメーターは環境に合わせて変更してください。
まず、FTPサーバー上からファイルを受信します。次に、ローカルのディレクトリを移動してFTPサーバへファイルを送信します。
ローカル側のディレクトリ内
ローカル側のディレクトリ内の状態を確認しましょう。
C:/Temp の中には サカエン というディレクトリのみ存在します。
C:/Temp/サカエン の中には saka-en というディレクトリと サカエン.txt というファイルが存在します。
C:/Temp/サカエン/saka-en の中には saka-en.txt というファイルが存在します。
FTPサーバ側のディレクトリ内
FTPサーバ側のディレクトリ内状態を確認しましょう。
/home/sakaen の中には Test というディレクトリが存在します。
/home/sakaen/Test の中には Test2 というディレクトリと text1.txt というファイルが存在します。
/home/sakaen/Test/Test2 の中には text2.txt というファイルが存在します。
FTP送受信テスト結果
実行結果はこんな感じになります。
ローカル側
C:/Temp/Test というディレクトリが増えました。
C:/Temp/Test の中には Test2 ディレクトリと text1.txt ファイルが存在します。
C:/Temp/Test/Test2 の中には text2.txt ファイルが存在します。
FTP受信がうまくいったようですね。
FTPサーバー側
/home/sakaen の中には サカエン というディレクトリが増えました。
/home/sakaen/サカエン の中には saka-en ディレクトリと サカエン.txt ファイルが存在します。
/home/sakaen/サカエン/saka-en の中には saka-en.txt ファイルが存在します。
FTP送信がうまくいったようですね。
Sponsored Links
参考サイト
おつかれさまでした。
Sponsored Links