ファイル転送結果を取得する方法とファイルアップロードの仕様について

このQ&Aのポイント
  • org.apache.commons.net.ftp.FTPClientを使ってファイル転送をしています。storeFileした結果を取得する方法と、ファイルアップロードの仕様について質問です。
  • ファイル転送時に時折ファイルサイズが0になってしまう現象が発生しています。一回目のアップロード結果を別の方法で取得することはできるでしょうか?また、複数ファイルアップロード時にログインとログアウトを繰り返す必要はあるのでしょうか?
  • 現在の仕様ではログイン⇒処理⇒ログアウト⇒ログイン⇒処理⇒ログアウトという処理になっていますが、この処理方法がファイルアップロードの失敗の原因になっているのではないかと危惧しています。また、ftpのモードはpassvにする必要があるのでしょうか?
回答を見る
  • ベストアンサー

FTPClientで転送結果(OKかFAIL)

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); } }

  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.1

環境がないのであくまで推測でのコメント アップロードに失敗しているときって 例外が発生したりはしていないの? 複数アップロードのときは このメソッドの外でFTPをOPEN/CLOSEすれば いいだけじゃないのかな? ダメだったらゴメンなさい

tori1202
質問者

お礼

お返事ありがとうございます。 例外は発生していないので、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モードじゃないと失敗する 確率が高そうな感じだったので、単にメソッドの仕様を変更するだけではだめのか??と 疑問に思っているところ(調査継続中です)です。

関連するQ&A

  • ファイル検索の方法

    フォルダ内にある、最後が「D00」で終わるファイルを表示させたいのですがうまくいきません。 以下のようなコードを書いたのですが、「*D00」の「*」の使い方が悪いのでしょうか? import java.io.*; class D00_gets { public static void main(String args[]) { String Dir_Name = "E:\\TEST\\TestData20040106"; File D_File = new File(Dir_Name); String list1[] = D_File.list(); String str01 = "*D00"; for(int i = 0;i<list1.length; i++) { if(list1[i].equals(str01)) System.out.println(list1[i]); } } }

    • ベストアンサー
    • Java
  • VBAでFTPファイル転送がうまくいかない

    利用環境  access:2003  os:xp このサイトを参考にvbaでFTPでファイル転送を実装しようとしています。 http://www.happy2-island.com/access/gogo03/capter90302.shtml 困っているのは、、エラーがでないのですが、ファイルが転送されないということです。 接続先やUserID,パスワードを間違えた場合は、ちゃんとエラーが表示されますので 接続まではできているのではないかと思いますが、最後のFTPファイル転送がうまくいきません。。 インターネットサービスのオープンとFTPサーバへの接続はうまくいっているようですが fcFTPPutFileの結果が何度やってもFALSEになります。 どのあたりを探れば問題がわかりますでしょうか? ご教示いただけますと助かります。 '■外部サーバーへファイルをアップロード Dim lngRC As Long 'インターネットサービスをオープンします lngRC = fcInternetOpen 'オープンに成功したらFTPサーバとの接続を行います If lngRC = 0 Then 'FTPサーバへ接続します lngRC = fcFTPConnect() '接続に成功したら、FTPサーバからファイルをアップロードします If lngRC = 0 Then Debug.Print Err.LastDllError '●↓この結果がFALSEになってしまい、ファイル転送ができません。。。 Call fcFTPPutFile(送り元ファイルパス&ファイル名_ , 送り先ファイルパス&ファイル名 _ , FTP_TRANSFER_TYPE_ASCII) Else MsgBox エラー内容 End If Else MsgBox エラー内容 End If ●↓この結果がFALSEになってしまい、ファイル転送ができません。。。 Public Function fcFTPPutFile(dLc As String, dRmt As String, dMd As Long) As Boolean 'dLc /ローカルファイル 'dRmt/リモートファイル 'dMd /転送モード 'FTPサーバへファイルをアップロード fcFTPPutFile = FtpPutFile(Pub_lngFtpHnd _ , dLc _ , dRmt _ , dMd _ , 0) End Function

  • 日本語ファイル名のFTPについて

    お世話になります。 日本語ファイル名のFTPを行っているのですが、ファイル名が文字化けして困っております。 解決策をご存知の方が、いらっしゃいましたら解決するための情報を頂けますでしょうか。 私が、使用しているのは、以下の環境となります。 【サーバ環境(FTP元、FTP先ともに同様となります。】 centOS5.5. jdk1.6 ftpを行う際、以下のようにして文字コード、転送モードを指定しております。 fp.setFileType(FTPClient.BINARY_FILE_TYPE); fp.setControlEncoding("UTF-8"); // ファイル送信 is = new FileInputStream(clientFilePath);// クライアント側 fp.storeFile(putFilePath, is);// サーバー側 String putFileNm = new File(putFilePath).getName(); String parentPath = new File(putFilePath).getParent(); String[] flist = fp.listNames(parentPath); for(int i=0; i<flist.length; i++) { if(putFileNm.equals(new File(flist[i]).getName())){ return true; } } FTP元、FTP先のサーバの文字コードも echo $LANGで確認しましたが、両方とも「ja_JP.UTF-8」になっております。 お手数お掛け致しますが、ご教授の程よろしくお願い致します。 以上、よろしくお願い致します。

    • ベストアンサー
    • Java
  • どこがエラーか確認してください…

    プログラムを作ったのですが、さまざまなエラーが出てしまいます。 与えた引数を数字と文字にわけるというプログラムです。 public class Selection { private static final char[] nch = { '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' };//0から9までの数字をchar型配列要素として定義 public static String numbersonly(String inputstr) { StringBuffer bfn = new StringBuffer(); for (int i = 0 ; i < inputstr.length(); i++) { for (int j = 0;j < nch.length() ; j++) { if(inputstr.charAt(i) == nch[j]) bfn.append(inputstr.substring(i)); //bfnにinsputstrのi番目の文字を付け足す } } return; bfn.toString(); //bfnをstring型に変えて戻り値 } //numbersonlyメソッドの場合と同様に以下も補う public static String lettersonly(String inputstr) { StringBuffer bfn =new StringBuffer(); boolean let; for (int i = 0; i < inputstr.length(); i++) { let = true; for(int j = 0; j < nch.length(); j++) { if(inputstr.charAt(i) == nch[j]) let =false; } if (let)bfn.append(inputstr.substring(i)); } return;bfn.toString(); } } はじめのchar型配列要素として定義するところでシンボルを解決できません、となっているので、そのほかのnchを使う部分(lengthメソッド、戻り値)にも影響が出ているのか、jのlengthメソッドもどちらともシンボル解決できず、それぞれreturnでは戻り値がありません、となります。

    • ベストアンサー
    • Java
  • ファイル読み込みを配列に入れる方法

    ファイルから数字を読み込んで 並び替えて出力するプログラムを作成しているのですが ファイルから一度に配列に取り込んで、その配列で並び変えたいのですが取り込みができないのです、int型の配列に一度に取り込むのは可能なのでしょうか? import java.io.*; class Sort { public static void main(String[] args) { String path = args[0]; File file = new File(path); FileReader fr = null; int[] buf = new int[(int)file.length()]; try { fr = new FileReader(file); fr.read(buf); for (int i=0; i<buf.length-1;i++) { int mini=buf[i]; int miniIndex = i; for(int j = i+1; j<buf.length;j++){ if(buf[j] < mini){ mini = buf[j]; miniIndex = j; } } buf[miniIndex] = buf[i]; buf[i] = mini; } for(int i =0; i<buf.length;i++) { System.out.print( buf[i]+","); } } catch (IOException e) { System.out.println("ファイル入力エラー"); } } } と作ってみたのですが‥ ご教授お願いいたします。

    • ベストアンサー
    • Java
  • Double.parseDoubleの使い方

    Java初心者です。 以下のブログラムをコマンドライン引数が実数の場合に処理できるよう にしたいのですが、うまくいきません。どうしたらいいでしょうか? 申し訳ありませんが、ご回答、よろしくお願いいたします。 public class Narabikae { public static void main(String[] args) { int i = 0, j = 0, k = 0; double[] num = new int[args.length]; for(i = 0; i < args.length; i++) { double num[i] = Double.parseDouble(args[i]); } if (0 < args.length) { for(j = 0; j < args.length-1; j++) { for(i = j + 1; i < args.length; i++ ) { if(num[j] > num[i]) { k = num[j]; num[j] = num[i]; num[i] = k; } } } for(i = 0; i < args.length; i++) { System.out.print(num[i]); if (i != args.length-1) { System.out.print(" ⇒ "); } } } else { System.out.println("並び替えできません。"); } } }

    • ベストアンサー
    • Java
  • ジオシティーズへのFTP転送

    ホームページ作成が終わり、仮にアップしてみました。最初はあるレンタルスペースに何の問題もなくアップ出来たのですが、思った以上に表示が遅かったので、ジオシティーズを試してみたく思いました。 新しく無料でYAHOO IDを取得し、そのIDでジオシティーズに申請し新しく、アドレスを取得しました。ところが、dreamweaverMX2004のソフトからアップロード出来ません。 サイトの定義を以下のように変更しました。 ・リモートサーバーにはどのように接続していますか 「FTP」 ・webサーバーのホスト名、またはFTPアドレスを指定してください 「ftp.geocities.jp」 ・ファイルはどのフォルダに保存しますか 「/」 ・FTPログイン名を入力してください 上記ID申請のもの(yahooトップページからログイン時に使用してるもの) ・FTPパスワードを入力してください 上記申請時に設定したパスワード です。そのほかは特にさわってません。 ftpソフトを使用する予定はありません。 ホント初心者の質問で申し訳ありませんがご回答お待ちしてます。

  • C# コードの意味を教えてください

    C#の勉強をはじめたところです。 以下のコードの ”ここが不明” とかいてあるところの意味を教えてください。  x => x.FilePath == pathこの意味が特に分かりません。 /////////////////////////// bool DoesNeedBackup(List<FileAndTime> fileAndTimes, string[] folderPaths, string[] filePaths) { if(fileAndTimes.Count != folderPaths.Length + filePaths.Length) return true; bool doesNeed = false; foreach(string path in filePaths) { FileAndTime fileAndTime = fileAndTimes.FirstOrDefault(x => x.FilePath == path);←ここが不明 ・   ・   ・ } クラスの定義 public class FileAndTime { public FileAndTime(string path, long tick) { FilePath = path; Tick = tick; } public long Tick { get; protected set; } = 0; public string FilePath { get; protected set; } = ""; public bool IsChecked { get; set; } = false; }

  • リストの値を取得したい

    こんにちは。リストの値取得について質問です。 ボタン1を押してファイルを開き、tokenで必要な値だけリストに表示させました。 そしてボタン2を押してリストに表示されている全データをプロンプトに表示させたいのです。 こんな感じで書いてみたんですけど、 if(s.equals("button2")==true){ String val = (String)list.getSelectedValue(); System.out.println(val); } これだと選択された1件しか表示されないんですよね(汗) ためしに if(s.equals("button2")==true){ for(int i=0;i<list.getsize;i++){ String val = (String)list.getSelectedValue(i); System.out.println(val); } } intはダメだとエラーが出ました。 色々調べてみましたがいまいちピンとこないです。 どなたかよろしければ知恵をお貸しください。 よろしくお願いします(^^;)

    • ベストアンサー
    • Java
  • getAttributeによるHTMLのタグ抽出について

    web上にあるHTMLで書かれた文書から、タグ別に抽出しようと思っています。以下にあるのはプログラムの一部です。 <a href~のタグだときちんと抽出できるのですが、<img src~から始まるタグでは抽出できなかったのです。どこがいけないのでしょうか? よろしくお願いします。 . . . public void handleStartTag(HTML.Tag tag, MutableAttributeSet attr, int pos) { if (tag.equals(HTML.Tag.A)) { href[i] = (String) attr.getAttribute(HTML.Attribute.HREF); i++; } else if (tag.equals(HTML.Tag.IMG)) { src[j] = (String) attr.getAttribute(HTML.Attribute.SRC); j++; } else { } } . . .

    • ベストアンサー
    • Java

専門家に質問してみよう