- PR -

FTPサーバから複数ファイルを取得する方法

1
投稿者投稿内容
みゆき
会議室デビュー日: 2004/07/02
投稿数: 6
投稿日時: 2006-02-10 15:03
いつも拝見させて頂いており、お世話になっています。
さて、困ったことがありまして、お知恵をお借りしたく、投稿させて頂きます。

FTPサーバから複数のファイルをダウンロードしたいのですが、
ソケット通信の初心者なので、まずネットからサンプルファイルを参照しながら作りました。
一つファイルのみダウンロードする場合は、問題なくできたのですが、
複数ファイルの場合はどう改造すればいいのかよく分かりませんので、
ご存知の方がいらっしゃいましたら是非教えてお願いします。



import java.io.*;
import java.net.*;

public class FTPSample {
private static final int CTRLPORT = 21; // ftpの制御用のポート
private static Socket ctrlSocket; // 制御用ソケット
private static PrintWriter ctrlOutput; // 制御出力用ストリーム
private static BufferedReader ctrlInput; // 制御入力用ストリーム
private static byte[] localHostAddress; // ローカルホストのアドレス

public static void main(String[] args) {
try {

String host = "192.168.4.233";
String loginName = "ftpuser";
String password = "ftpuser";
String dirName = "/home";
String fileName = "FTPTEST.txt";

// 接続します
ctrlSocket = new Socket(host, CTRLPORT);
localHostAddress = ctrlSocket.getLocalAddress().getAddress();
ctrlOutput = new PrintWriter(ctrlSocket.getOutputStream());
ctrlInput = new
BufferedReader(new InputStreamReader(ctrlSocket.getInputStream()));

// ユーザー認証します
ctrlOutput.println("USER " + loginName);
ctrlOutput.flush();
ctrlOutput.println("PASS " + password);
ctrlOutput.flush();

// 指定したディレクトリに移動します
ctrlOutput.println("CWD " + dirName);
ctrlOutput.flush();

// バイナリモードに設定します
ctrlOutput.println("TYPE I");
ctrlOutput.flush();

// ダウンロードします
FileOutputStream fos = new FileOutputStream(fileName);
Socket dataSocket = dataConnection("RETR " + fileName);
BufferedInputStream instr = new BufferedInputStream(dataSocket.getInputStream());
int n;
byte[] buff = new byte[1024];
while ((n = instr.read(buff)) > 0) {
fos.write(buff,0,n);
}
dataSocket.close();
fos.close();

// 接続を閉じます
ctrlOutput.close();
ctrlInput.close();
ctrlSocket.close();
}catch (Exception e) {
e.printStackTrace();
}
}

/**
* データ送受信用ソケットを取得します
*/
private static Socket dataConnection(String ctrlcmd)
throws IOException,UnknownHostException {
String cmd = "PORT ";
ServerSocket serverDataSocket = new ServerSocket(0,1);

for (int i =0; i < 4; i++) {
cmd = cmd + (localHostAddress[i] & 0xff) + ",";
}
cmd = cmd + (((serverDataSocket.getLocalPort())/256) & 0xff)
+ ","
+ (serverDataSocket.getLocalPort() & 0xff);

ctrlOutput.println(cmd);
ctrlOutput.flush();
ctrlOutput.println(ctrlcmd);
ctrlOutput.flush();

Socket dataSocket = serverDataSocket.accept();
serverDataSocket.close();
return dataSocket;
}
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-02-10 15:39
引用:

みゆきさんの書き込み (2006-02-10 15:03) より:

一つファイルのみダウンロードする場合は、問題なくできたのですが、
複数ファイルの場合はどう改造すればいいのかよく分かりませんので、


ダウンロードするファイル名を複数にすればいいんですよ。

ただ、すぐに複数にしてしまう前に、
まずはfileNameを要素が1コの配列にすることをお勧めします。
こんな感じ。
コード:
String[] fileName = new String[1];
fileName[0] = "FTPTEST.txt"; 


これでプログラムがちゃんと動くようにする。

プログラムがちゃんと動いたら、
次は、fileNameを使ってループをするようにしましょう。

これがちゃんと動いたら、fileNameの要素数を増やすのに挑戦しましょう。

とにかく大切なことは、まずは動くものを作る(これは実現できてますよね)、
そして、それを少しずつ改造していくことです。
引用:

ご存知の方がいらっしゃいましたら是非教えてお願いします。


上記のものでヒントになるかと思います。
実際に自分でやってみて、うまくいかなかったら、
改めてそれを質問するのがよろしいかと。
がんばってください。
みゆき
会議室デビュー日: 2004/07/02
投稿数: 6
投稿日時: 2006-02-10 16:38
ご返事ありがとうございました。
教えていただいた方法で改造したら、複数のダウンロードできました♪
一つ気になるのは、ファイアウォールを無効にしないと(XPのSP2で動作したので)
ポートが開けないことです。
試しに、Windowsファイアウォール->例外の設定に空いているポート(例:4000)を追加して、ServerSocket serverDataSocket = new ServerSocket(4000,1)を使うようにしたのですが、Socket dataSocket = serverDataSocket.accept()のところでフリーズしてしまいました。。。
原因はご存知でしょうか?


Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-02-10 17:33
引用:

みゆきさんの書き込み (2006-02-10 16:38) より:

一つ気になるのは、ファイアウォールを無効にしないと(XPのSP2で動作したので)
ポートが開けないことです。


ファイアウォールでは、利用するポート以外は閉じられているものです。
ftpだったら、Windowsファイアウォールの[詳細設定]->[サービス]に、
「FTPサーバー」の項があります。
引用:

試しに、Windowsファイアウォール->例外の設定に空いているポート(例:4000)を追加して、ServerSocket serverDataSocket = new ServerSocket(4000,1)を使うようにしたのですが、Socket dataSocket = serverDataSocket.accept()のところでフリーズしてしまいました。。。


フリーズしているのではなく、クライアントからの接続を待っているんだと思います。
さて、私が助言できるのはここまででして・・・。

実は私、socketを使った経験は少ないのであります。m(_ _)m
で、気になるのは、dataConnection()の中で利用されているServerSocketが、
自分自身に接続しているように見えるのは私の気のせいですか?
ダウンロードのためのストリームなら、ctrlSocketにretrコマンドを送り込めば、
ctrlSocketからとれると思うんですが・・・。
申し訳ないですが、私はここまでです。

[ メッセージ編集済み 編集者: Edosson 編集日時 2006-02-10 17:34 ]
AME
会議室デビュー日: 2006/10/17
投稿数: 13
投稿日時: 2006-10-19 18:52
この場を借りて、聞きたいのですが、
大量ファイルを一括で送信したいときはどうしますか?
例:
String[] fileName = new String[1];
fileName[0] = "FTPTEST1.txt";
fileName[1] = "FTPTEST2.txt";
fileName[2] = "FTPTEST3.txt";
...
ご回答お願いします。
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-10-19 20:26
またずいぶんと前の投稿を・・・。
しかも、私が噛んでるし。w

引用:

AMEさんの書き込み (2006-10-19 18:52) より:

大量ファイルを一括で送信したいときはどうしますか?


このスレを、「受信」を「送信」に読み替えればいいです。

<追記>
投稿した後で、自分が「受信」という語は使っていないことに気づいた。orz
読み替えが必要ないなら、まんまでいいってことだよね。

[ メッセージ編集済み 編集者: Edosson 編集日時 2006-10-19 20:35 ]
1

スキルアップ/キャリアアップ(JOB@IT)