FTPサーバー上の指定したパスがディレクトリとして存在するかを確認する際は、Apache Commons Netが提供するFTPClientクラスを利用するのが標準的です。単純な文字列一致ではなく、プロトコルが返すファイル属性を検証することで、同名のファイルとディレクトリが混在している場合でも正確に判定できます。
まず、ビルドツールに依存ライブラリを追加します。Mavenを使用している場合は、pom.xmlに以下の定義を追記してください。
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.9.0</version>
</dependency>
実装では、接続確立からリモートノードの検証、リソースの解放までを一貫した形で記述します。以下の例では、リスト取得機能とファイルタイプフラグを組み合わせて安全にチェックするロジックを採用しています。
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;
import java.io.IOException;
public class RemoteFileSystemValidator {
public static boolean verifyDirectoryExists(String targetHost, int targetPort, String account, String credential, String targetPath) {
FTPClient session = new FTPClient();
boolean validationResult = false;
try {
session.connect(targetHost, targetPort);
if (!FTPReply.isPositiveCompletion(session.getReplyCode())) {
throw new IOException("セッション確立に失敗: " + session.getReplyString());
}
if (!session.login(account, credential)) {
throw new IOException("認証プロセスでエラーが発生");
}
session.enterLocalPassiveMode();
session.setFileType(FTP.BINARY_FILE_TYPE);
FTPFile[] remoteEntries = session.listFiles("/");
for (FTPFile node : remoteEntries) {
if (node.getName().equals(targetPath) && node.isDirectory()) {
validationResult = true;
break;
}
}
} catch (IOException e) {
System.err.println("検証処理中に例外発生: " + e.getMessage());
} finally {
try {
if (session.isConnected()) {
session.logout();
session.disconnect();
}
} catch (IOException ex) {
System.err.println("セッション切断に失敗: " + ex.getMessage());
}
}
return validationResult;
}
}
この実装では、listFiles()メソッドで取得したFTPFileオブジェクトのisDirectory()メソッドを参照しています。FTPサーバーが返すメタデータに基づいてノードタイプを判定するため、名前だけの部分一致や正規表現によるフィルタリングよりも信頼性が高まります。接続処理ではFTPReply.isPositiveCompletion()でステータスコードを早期検証し、ネットワーク障害や認証ミスを即座に捕捉する設計にしています。
セッション管理においては、finallyブロック内でlogout()およびdisconnect()を確実に実行することで、コネクションプールの枯渇やリソースリークを防いでいます。また、ファイアウォール環境下での転送を安定させるためにenterLocalPassiveMode()を有効化しています。
検証対象の基準パスを動的に変更したい場合は、changeWorkingDirectory()を実行した後にlistFiles()を呼び出すようにロジックを拡張可能です。タイムアウト値や転送バッファサイズは、setConnectTimeout()およびsetDataTimeout()で環境に合わせて調整できます。