別の記事で掲載したAppMainから呼び出す、共通インターフェースを実装する、個別クラスについて記述する。
FileFinderと同じようなクラスだが、ここでは所定のフォルダ配下を再帰的に検索し、指定した名前のファイルを見つけたら、別のディレクトリにコピーするユーティリティクラスをサンプルとする。
FileFinderと本クラスの2クラスのサンプルを記載したのは、同じ1つのバッチ呼び出しの入り口から異なる2つ以上の機能を呼び出すことができることを例示するためである。
<以下、ソースコード>
package cmd;
import java.io.File;
import org.apache.log4j.Logger;
import exception.AppException;
public class FilePicker implements CommandInterface {
/** ログ */
private final Logger log = Logger.getLogger(this.getClass());
/** 結果出力ディレクトリ */
private File resultDir;
/**
* コマンドラインインターフェースです。 <br>
* 本クラスの機能をバッチから呼び出す場合は、このメソッドを実行します。
*
* @param args
* コマンドライン引数
* @throws Exception
*/
@Override
public void doMain(String[] args) throws AppException {
// コマンドライン引数が指定されていない場合は、エラーとする
if (args == null || args.length == 0) {
throw new AppException("コマンドライン引数がありません。");
}
// 第1引数が自クラスを指していない場合は、エラーとする
if (!args[0].contains(this.getClass().getName())) {
throw new AppException("不正な呼び出しです。 args[0] : " + args[0]);
}
// 引数が足りない場合は、エラーとする
String paramName1 = "検索対象ディレクトリ名";
String paramName2 = "検索するファイル名";
String paramName3 = "結果出力ディレクトリ名";
if (args.length < 4) {
throw new AppException("引数が足りません。 (第1引数 " + paramName1 + ", 第2引数 "
+ paramName2 + ", 第3引数 " + paramName3 + ")");
}
// 引数をログに記録する
String crlf = System.getProperty("line.separator");
String msg = "ファイル抽出" + crlf + "\t" + paramName1 + " : " + args[1]
+ crlf + "\t" + paramName2 + " : " + args[2] + crlf + "\t"
+ paramName3 + " : " + args[3];
log.info(msg);
// ファイル抽出を実行する
doPickupFile(args[1], args[2], args[3]);
}
/**
* 検索対象ディレクトリを検索してファイルを抽出します。
*
* @param targetDirName
* 検索対象ディレクトリ名
* @param searchFileName
* 検索するファイル名
* @param resultDirName
* 結果出力ディレクトリ名
* @throws AppException
*/
public void doPickupFile(String targetDirName, String searchFileName,
String resultDirName) throws AppException {
// 検索対象ディレクトリが存在しない場合は、エラーとする
File targetDir = new File(targetDirName);
if (!(targetDir.exists() && targetDir.isDirectory())) {
throw new AppException("検索対象ディレクトリが存在しません。 " + targetDirName);
}
// 結果出力ディレクトリが存在しない場合は、エラーとする
resultDir = new File(resultDirName);
if (!(resultDir.exists() && resultDir.isDirectory())) {
throw new AppException("検索対象ディレクトリが存在しません。 " + resultDirName);
}
// ファイル抽出を実行する
doPickupFileRecursive(searchFileName, targetDir, resultDir);
}
/**
* ディレクトリを再帰的にたどって、ファイルをコピーします。
*
* @param searchFileName
* 検索するファイル名
* @param currentDir
* カレントディレクトリ
* @param currentResultDir
* カレント結果出力ディレクトリ
* @throws AppException
*/
private void doPickupFileRecursive(String searchFileName, File currentDir,
File currentResultDir) throws AppException {
// ディレクトリ内にファイルがなければ、処理を終了する
File[] files = currentDir.listFiles();
if (files == null || files.length == 0) {
return;
}
// ディレクトリ内の全てのファイルを処理するまでループ
for (File file : files) {
if (file.isDirectory()) {
// ディレクトリの場合は、結果出力先に同じディレクトリを作成する
File resultDir = new File(currentResultDir.getAbsolutePath()
+ File.separator + file.getName());
if (!resultDir.exists()) {
resultDir.mkdirs();
}
// 本処理を再帰的に呼び出す
doPickupFileRecursive(searchFileName, file, resultDir);
} else {
// ファイルの場合は、パターンにマッチするか判定を行う
if (!file.getName().matches(searchFileName)) {
continue;
}
// ファイルが見つかったらログファイルに書き込みを行う
String destFileName = currentResultDir.getAbsolutePath()
+ File.separator + file.getName();
String crlf = System.getProperty("line.separator");
String msg = "ファイルをコピーします。" + crlf + "\tコピー元 : "
+ file.getAbsolutePath() + crlf + "\tコピー先 : "
+ destFileName;
log.info(msg);
// ファイルをコピーする
copyFile(file.getAbsolutePath(), destFileName);
}
}
}
/**
* ファイルをコピーします。
*
* @param srcFileName
* コピー元ファイル名
* @param destFileName
* コピー先ファイル名
*/
private void copyFile(String srcFileName, String destFileName)
throws AppException {
// ファイルエンコード(文字化け)の問題があるため、copyコマンドでコピーする
String[] cmd = { "cmd", "/c", "copy", srcFileName, destFileName };
ProcessBuilder pb = new ProcessBuilder(cmd);
Process process;
try {
process = pb.start();
process.waitFor();
} catch (Exception e) {
throw new AppException(e);
}
}
}
0 件のコメント:
コメントを投稿