プロが教えるわが家の防犯対策術!

org.apache.commons.net.ftp.FTPClientを使ってファイル転送をしています。

storeFileした結果を取得する方法はないでしょうか。
結果がOKであれば、そのまま処理を終わり、FAILであれば再度アップロード
させたいと思っています。

上記に至った経緯は下記の通りです。

もともと、
ログイン⇒ファイルアップロード⇒ログアウト
というメソッドを作り、複数ファイルを上記メソッドを使ってアップロードして
いるのですが、時折(不定期に)ファイル転送に失敗してファイルサイズが
0になっていました。

そこで、下記のようにメソッドの仕様を変更ました。
ログイン⇒アップロード⇒アップしたファイルをダウンロードしてサイズチェック
⇒ファイルサイズが0の場合は再度アップード⇒ログアウト
すると今度は、一回目のアップロードは問題ないのに、ダウンロードが失敗
してファイルサイズが0となり、再アップロードするとファイルサイズが0になって
しまう(この時のFTPのステータスはOKでした)という現象が発生してしまい
ました。

ファイルダウンロード時にFAILになるようでは、意味がいないので、一回目の
アップロード結果を別の方法で取得できないか、というのが今回質問に至った
経緯です。

ちなみに、今の仕様だと複数ファイルアップする場合、
ログイン⇒処理⇒ログアウト⇒ログイン⇒処理⇒ログアウト・・・
という処理になっています。
これって不必要にログインとログアウトを繰り返しているように思うので、それが
ファイルアップロード失敗する一因ではと危惧しているのですが、その点もご意見
いただければ嬉しいです。
なお、
ログイン⇒ファイル1アップ⇒ファイル2アップ⇒…⇒ログアウト 
に変更する場合、ftpのモードはpassvにする必要がありますか?現在はpassvではあ
りません。

参考までに、Javaソースを下記に記載しておきます。

どうぞよろしくお願いします。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
public String putFile(String filepath, byte[] bytes) throws IOException {

FTPClient ftp = null;
ByteArrayInputStream bais = null;
ByteArrayOutputStream baos = null;

try {
// FTP 接続を行う
ftp = connect();

// ファイル送信
bais = new ByteArrayInputStream(bytes);

filepath = baseDir + filepath;

// ディレクトリが存在しなければ生成する
String path = "";
String[] dirs = filepath.split("/+");
for (int i = 0; i < dirs.length - 2; i++) {
System.err.println("dirs:" + dirs[i]);

if(dirs[i].equals("")){
continue;
}

path += dirs[i] + "/";

FTPFile[] files = ftp.listFiles(path);
int j;
for (j = 0; j < files.length; j++) {
if (files[j].getName().equals(dirs[i + 1]))
break;
}
if (j < files.length)
continue;

if (!dirs[i + 1].equals("..") ){
ftp.makeDirectory(path + dirs[i + 1]);
}

}

ftp.storeFile(filepath, bais);

// ファイルサイズが0になる問題対応
// ファイルアップ後にファイルを取得してサイズが0なら再アップする
// ファイル受信
baos = new ByteArrayOutputStream();
ftp.retrieveFile(filepath, baos);

if(baos.toByteArray().length == 0)
ftp.storeFile(filepath, bais);

return filepath;
}
catch (IOException ioe) {
String msg = String.format("FTP によるファイル送信に失敗しました。(%s)", ioe.getMessage());
log.error(msg);
throw new FileTransferException(msg);
}
finally {
close(ftp, bais);
}

}

A 回答 (1件)

環境がないのであくまで推測でのコメント



アップロードに失敗しているときって
例外が発生したりはしていないの?


複数アップロードのときは
このメソッドの外でFTPをOPEN/CLOSEすれば
いいだけじゃないのかな?
ダメだったらゴメンなさい
    • good
    • 0
この回答へのお礼

お返事ありがとうございます。

例外は発生していないので、ftpの問題と気づくまで時間がかかってしまいました。
一応try catchしているのですが…

ftp(vsftp)のログを見ると下記の様にFAILとなっていたので、FTP失敗してるんだと
なったわけです。

Wed Apr 4 12:10:04 2012 [pid xxxxx] [hoge] FAIL UPLOAD: Client "xxx.xxx.xxx.xxx", "/home/release/html/xxx.html", 0.00Kbyte/sec

Thu Apr 5 11:00:02 2012 [pid xxxxx] [hoge] FAIL DOWNLOAD: Client "xxx.xxx.xxx.xxx", "/home/release/html/xxxx.gif", 0.00Kbyte/sec


そうですね、複数アップロードの時はご指摘の通り接続をこのメソッドの外で
行うように変更する予定です。

ただ、いろいろと調べるとftpで複数ファイルアップの際はPASSIVモードじゃないと失敗する
確率が高そうな感じだったので、単にメソッドの仕様を変更するだけではだめのか??と
疑問に思っているところ(調査継続中です)です。

お礼日時:2012/04/05 15:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!