ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Javaの課題丸投げコミュのFTPのlcdコマンドについて

  • mixiチェック
  • このエントリーをはてなブックマークに追加
改めて、トピックを作成させていただきます。

JAVAでSocketを使ったFTPクライアント
プログラムを作っています。

クライアントのFTPホームディレクトリ以外から
サーバへデータをputしたいのですが、ローカルパスを指定する
所謂「lcdコマンド」を発行することができず
その機能を実現できないでいます。
フルパスでファイルを指定してもSTORプロトコルは
失敗してしまうようです。

好きな場所からファイルをPUTするにはどうすれば
よいのか、もしくは、ソケットプログラムでそういうことは
できないのでしょうか?

情報をお持ちの方、教えて頂けないでしょうか。
よろしくお願いします。

コメント(4)

LCDコマンドは、クライアント側の作業ディレクトリを変更するコマンドだとおもいますが・・・
そのためLCDコマンドを実行しても、サーバ側へ命令が送信されることはありません。
サーバ側もLCD命令を受信しても何もしないはずです。

FTPの場合、クライアント側とサーバ側のそれぞれで作業ディレクトリを保持しています。
CDコマンドでサーバ側の、LCDコマンドでクライアント側の作業ディレクトリを変更することになります。
単純にLCDコマンドを実行したら、クライアント側の作業ディレクトリを変更するだけでいいとおもいます。
おそらくクライアント側で
 File workDir = new File("d:/");
のような形で(String型とかでもいいですが)、作業ディレクトリ情報を持っていると思いますが、
 LCD d:/temp
のようにLCDコマンドを実行した場合、
 workDir = new File("d:/temp/");
とするだけだと思います。
あとはSTORコマンドを実行した場合、d:/temp/ にあるファイル等を読み込んで処理するだけだと思います。

(なお、私自身、FTPサーバプログラムを作ったことはありますが、
FTPクライアントは作ったことはないので、どこか勘違いをしているかもしれません。)
お返事ありがとうございます。とても助かります。
試してみましたところ、下記の二行を実行してみたところ

File workDir = new File("d:/");
workDir = new File("d:/temp/");

LCDの動きをせず、指定した場所にあるはずファイルが
「見つかりません」と出てしまいます。
workDir = new File("d:/temp/"); は
workDir = new File("lcd d:/temp/"); でしたでしょうか?
それとも、workDirとPUTしたいファイル名を指定して、STORプロトコルに
送らなければならないということでしょうか?

拙い理解で申し訳ありません、ご教授下さい。
んー、私の説明が下手で、いろいろ食い違っているような気がしてならないですが・・・

まず、かすみさんが作成されているFTPクライアントのプログラムでは、
基準となる作業ディレクトリ情報は持っていないのでしょうか?

基本的にクライアント側の作業ディレクトリ情報は、あくまでクライアントが処理を
行うための情報であり、それ自体をサーバに送信する必要は全くありません。

クライアント内の作業ディレクトリを
/** 作業パス */
String workDir = "c:/";
と定義した場合・・・

たとえば、クライアント側で
「C:/temp/sample.txt」
をサーバに転送したい場合、
クライアントで
「LCD temp」
のような形でLCDコマンド実行して場合、クライアント内の現在の作業ディレクトリ情報を
workDir = "c:/temp";
と変更します。(本来であればディレクトリの有無などもチェックすべき)
次に
「STOR sample.txt」
を実行することでクライアント内で現在の作業ディレクトリ情報workDirとSTORの引数「sample.txt」から対象となるファイルを
File transferFile = new File(workDir, "sample.txt");
とします。(もちろん、transferFileが存在するかのチェックも行うべきです。transferFile.isFile()でチェックできます )
実際にはこの時点ではこのsample.txtを操作はせず、まずはSTORコマンドをサーバに転送したうえで
サーバからの返答に応じてデータチャネルの接続を行います。
データチャネルが接続できた時点で以下のような形でファイルを開いてデータを読み込んで転送を行います。
OutputStream out = socket.getOutputStream();
InputStream in = new FileInputStream(transferFile);
byte[] data = new byte[65536];
while (in.available() > 0) {
int len = in.read(data);
if (len > 0) {
out.write(data, 0 ,len);
}
}
in.close();
なお、io処理が入るので適宜try-catchでくくる必要があります。


一つ気になっているのは、FTPの動作がどのようなものであるのかどこまでしっているんでしょうか・・・。
たとえば、コントロールチャネル(ポート21)とデータチャネル(ポート22[最近では1024以降を使うことが推奨されてるはず])の2種類の通信チャネルを使用するとか。
データチャネルの接続は、クライアント側から行う場合とサーバ側からおこなうことがあるとか。
とても丁寧に説明してくださって、ありがとうございます。
この質問に関する私のスキルとしては、オブジェクト指向プログラミングが初めてで
FTPはコマンドと、制御用とデータ用のソケットを使ってやり取りするのだなということを
浅く知っている程度です。初心者の私にできる仕事ではないのかも知れませんが・・・がんばります。

ご説明を熟読して、自分なりに考えて作ってみました。
結論から言いますと、うまくいきました。
本当に助かりました。重ねてお礼申し上げます。

全くもって誤解していたのは「LCDコマンドを発行するはずだ」という思い込みでした。
結果的にはLCDをFTPクライアントに発行することと、同じ動作となりましたが
ファイルストリームで、直パスを指定して書き込むのですね。
あやめさんのご説明。メモ帳に貼り付けて、繰り返し読んで理解を深めたいと思っています。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Javaの課題丸投げ 更新情報

Javaの課題丸投げのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。