質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

16719閲覧

Java Commons.netを用いたFTPクライアントについての質問

puti

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2015/03/03 07:26

編集2015/03/03 09:26

お世話になっております。
現在、JavaでFTPアップロードを行う。 - sinsengumi血風録を参考にFTP通信を行うプログラムを作成しています。

送信中はサーバーにlockファイルを作成し、送信が終わったら作成したlockファイルを削除するプログラムにしたいのですが、下記のように作成したところlockファイル自体の作成と削除はできるのですが、肝心のファイル送信自体がうまく行きません。
ストリームの理解が足りないまま併用をしているのが原因だと思うのですが、ご教授をお願いします。

lang

1 private static void execute() throws Exception { 2 3 FTPClient ftpClient = new FTPClient(); 4 OutputStream out = null; 5 6 try { 7 8 // エンコーディングの設定は、connectする前に行う。 9 ftpClient.setControlEncoding("UTF8"); 10 11 // FTPサーバに接続 12 ftpClient.connect(FTP_HOST); 13 14 ftpClient.setSoTimeout(20000); 15 16 // ログイン 17 ftpClient.login(FTP_USER, FTP_PASSWORD); 18 19 // PASVモードに設定 20 ftpClient.pasv(); 21 22 // データの変換モードをバイナリに設定 23 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); 24 25 //ロックファイル作成 26 out = ftpClient.storeFileStream("0001.lock"); 27 out.close(); 28 29 Thread.sleep(2000); 30 31 // ファイル転送 32 FileInputStream fis = new FileInputStream(UPLOAD_FILE); 33 34 ftpClient.storeFile(UPLOADED_FILENAME, fis); 35 36 Thread.sleep(2000); 37 38 ftpClient.deleteFile("0001.lock"); 39 40 } catch (NumberFormatException e) { 41 throw new Exception("FTPポートの値が数値ではありません。", e); 42 } catch (SocketException e) { 43 throw new Exception("Socket通信に失敗しました。", e); 44 } catch (FileNotFoundException e) { 45 throw new Exception("アップロードするファイルが見つかりません。", e); 46 } catch (IOException e) { 47 throw new Exception("IOレベルで例外が発生しました。", e); 48 } finally { 49 if (out != null) { 50 out.close(); 51 } 52 if (ftpClient.isConnected()) { 53 try { 54 ftpClient.logout(); 55 ftpClient.disconnect(); 56 System.out.println("disconnect complete"); 57 } catch (IOException e) { 58 // ignore 59 } 60 } 61 } 62 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

(追記)

元のコードで同じ問題が発生することを確認しました。

lockファイルの送信後にはステータス150が返されています。
これはデータコネクション(ファイル転送のためのコネクション)が確立した状態のままになっていて、転送が完了していないということなのではないかと思います。

正しい解決方法かどうか自信がありませんが、lockファイルの転送後にftpClient.getReply();を入れることで、転送が終わったことを通知できるようです。つまり、226 Transfer Completeになります。

lang

1//ロックファイル作成 2OutputStream out = ftpClient.storeFileStream("0001.lock"); 3out.close(); 4ftpClient.getReply(); // ◆◆ ここ ◆◆

(最初の回答)

下記ページにあるように、それぞれの処理後にftpClient.getReplyString()を出力して、応答の内容を確認してみてください。
JavaでFTPアップロードを行う。 - sinsengumi血風録

投稿2015/03/03 09:01

編集2015/03/03 15:20
argius

総合スコア9390

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

puti

2015/03/03 09:08

回答ありがとうございます。 応答電文は 220 Microsoft FTP Service 230 User logged in. 227 Entering Passive Mode (************). 200 Type set to I. 200 PORT command successful. となっており、ファイルの送信自体は成功している、という具合です。
argius

2015/03/03 09:38

うまく行かないと書かれていますが、具体的にはどのような問題があるのですか?
puti

2015/03/03 09:45

・指定した名前の.lockファイルは作成されます。 ・実行してほしいftpClient.storeFile(UPLOADED_FILENAME, fis); 部分で正常に送信処理が行われていません。 ・UPLOADED_FILENAMEと同名のファイルをFTPサーバーに配置した状態でプログラムを実行するとUPLOADED_FILENAME名のファイルが削除されます。
tsuntsun

2015/03/03 09:56

ロックファイルの作成と削除をコメントアウトして実行するとどうなりますか?
puti

2015/03/03 10:01

参考サイトままのプログラムになるため、正常に転送が可能です。 上記プログラムのロックファイル作成が生きている状態でファイル転送を行うと18:45に書き込んだコメントの通りになるため、該当場所の作りが悪いとは思うんですが……。
argius

2015/03/03 14:31

追記しました。
puti

2015/03/04 01:53

ありがとうございます。 ftpClient.getReply()を仕込んだところ、期待通りの動作をしてくれました。 参考にしたサイトのサブルーチンをlockファイル作成後に仕込んだ場合にエラーを吐いた為仕込まないようにしていたのがよくなかったですね…。わざわざ再現ありがとうございました。
guest

0

ロックファイルの獲得に、
File lockFile = new File("/tmp/hoge.lock");
try (FileChannel fc = FileChannel.open(lockFile.toPath(), StandardOpenOption.CREATE, StandardOpenOption.WRITE);
FileLock lock = fc.tryLock()) {
if (lock == null) {
// 他プロセスロック中
throw new RuntimeException(MessageFormat.format("File locked another proc."));
}
{
//ロック獲得後の処理
}
}

の様なコードを書かない理由は置いといて(笑)

connect後にreplyを確認していないとか、loginの成否を判定していないとかツッコミ所満載ですね。
ザックリですが、こんなコードになるかと。
try {
//接続
ftpclient.connect(host, port);
int reply = ftpclient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
//接続エラー処理
例外throw
}

//ログイン if (ftpclient.login(FTP_USER, FTP_PASSWORD) == false) { // ログインエラー処理 例外throw } //ファイル転送モード設定 ftpclient.setFileType(FTP.BINARY_FILE_TYPE); // PASVモードに設定 ftpclient.pasv(); //ファイル転送 ftpclient.storeFile(UPLOADED_FILENAME, fis); //"ファイル転送完了

} catch (IOException e) {
//エラー処理
throw e;
} finally {
try {
ftpclient.disconnect(); //接続解除
} catch (IOException e) {
}
}

投稿2015/03/03 09:15

tsuntsun

総合スコア199

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

puti

2015/03/03 09:43

申し訳ない、追記したサイトに追加するだけ、という形式で行っていたため、サブルーチンの方を書かずに質問してしまいました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問