この記事では、Javaで既存の利用可能なライブラリを使用してFTPクライアントコードを作成し、アプレットコントロールに開発して、Webに基づいてコントロールをアップロードおよびダウンロードする方法を作成します。一連のFTPカスタマーライブラリに基づいて、この記事は、進行状況バー、ブレークポイントの継続、内部ネットワークのマッピング、アプレットのコールバックJavaScript機能など、より一般的で強力なJ-FTPライブラリの1つで詳細な説明とコード実装を提供します。この記事がヒスイを引き付けるのに役割を果たすことが期待されています。
1。はじめに
プロジェクトの実装中に、Webベースのファイルのアップロードとダウンロード要件が登場しました。州全体(または全国)のユーザーは、特定のセンターのファイルサーバーにいくつかのファイルをアップロードする必要があります。これらの文書は、いくつかの大規模なエンジニアリング構造に使用されています。これには、数千万人または数億人の元の建設プロジェクトが含まれる場合があります。ファイルには3つの異なる特性があります。1つは、ファイルが大きく、50mに達する可能性があることです。 2つ目は、ファイルの数が大きく、約15である可能性があることです。 3つ目は、データセキュリティの観点からデジタル署名とデータ暗号化が必要であることです。
まず、HTTPベースの伝送方法を検討してください。しかし、比較を通じて、上記のニーズが満たされていることがすぐにわかりました。
1:HTTPプロトコルを使用したアップロードは、Webプログラミングの利便性により適しているようです。 1M未満のファイルのアップロードは、FTPプロトコルを使用してファイルをアップロードするよりもわずかに高速です。しかし、バッチと大きなファイルの転送については何もすることはないかもしれません。もちろん、FTPとは異なり、サーバー側でFTPサービスを開始する必要があるなど、利点もあります。
2:FTPプロトコルを使用して1Mを超えるファイルを使用してファイルをアップロードすると、HTTPよりも高速です。ファイルが大きいほど、アップロード速度はHTTPアップロード速度よりも数倍高速になります。 Javaでプログラムを書きます。 FTPはHTTPよりも便利です。
著者はかつてVBを使用し、ActiveXコントロールを作成してバッチファイルをアップロードおよびダウンロードしましたが、その機能も非常に強力です。 CABファイルやOCXには特別なデジタル署名がないため、安全なサイトのセットアップ、クライアントのセキュリティレベルの削減など、クライアントに退屈な設定を実行する必要があります。一部のソリューションは放棄されています。
同時に、ファイルをデジタル署名してクライアントに暗号化する必要があることを考慮すると、アプレットを使用してそれらを実装することが決定されました。 。ファイルをアップロードする前に、ローカルUSBKEYキー情報をクライアントから取得して、アップロードされたファイルの暗号化と署名処理を完了することができます。アプレットを使用するには、クライアントにJREランタイム環境をインストールする必要がありますが、クライアントの管理と使用に不便をもたらしますが、このような多数のファイルとファイルのセキュリティを比較するのは比較的小さい価格かもしれません。
動作環境を要約するには:
FTPサーバー側: Serv-U、プロフェッショナルFTPサーバーサイドプログラム、インターネット上に既製のソフトウェアダウンロードがあります。もちろん、読者は説明するサーバー側のFTPファイル受信プログラムを記述することもできます。特別な要件や関数がない場合、Serv-Uは一般的なアップロードとダウンロードのニーズを満たすことができるはずです。
クライアント: Java Appletは、Javaを人気にした技術であり、MicrosoftのActiveXに匹敵すると主張していました。もちろん、JavaにはJava FXがあります。それはアプレットの代わりですか?
アプリケーション環境:インターネット、究極の目的。
2。Java FTPクライアントライブラリの選択
シナリオを想像してみましょう - リモートコンピューターで実行されているFTPサーバーからファイルをアップロードおよびダウンロードする純粋なJavaアプリケーションを書きたいと思います。また、ファイル名、データ、ファイルサイズなど、ダウンロード用のリモートファイルの基本的なファイル情報を取得する必要があります。
FTPプロトコルハンドラーをゼロから書くことは可能であり、おそらく興味深いものですが、作業も困難で、長く、潜在的に危険です。私たちはそのような処理プログラムを自分で書くのに時間、エネルギー、またはお金を費やすことを嫌がっているので、すでに存在する再利用可能なコンポーネントに目を向けます。また、多くのライブラリがオンラインで入手できます。
私たちのニーズに合った優れたJava FTPクライアントライブラリを見つけることは、見た目ほど簡単ではありません。それどころか、これは非常に苦痛で複雑な作業です。まず、FTPクライアントライブラリを見つけるのに時間がかかります。第二に、既存のすべてのライブラリを見つけた後、どちらを選択する必要がありますか?各ライブラリは、さまざまなニーズに適しています。これらのライブラリはパフォーマンスが同等ではなく、設計に基本的な違いがあります。各ライブラリには独自の特性があり、異なる用語を使用してそれらを説明します。したがって、FTPクライアントライブラリを評価して比較することは難しい作業です。
再利用可能なコンポーネントを使用することは提唱されたアプローチですが、この場合、最初は落胆することがよくあります。後で、私は少し恥ずかしいかもしれません。良いFTPライブラリを選択した後、その後の作業は非常に簡単です。簡単なルールに従ってください。現在、SimpleFTP、J-FTPなど、その他多くのFTPClientsなど、多くの公開および無料のFTPクライアントライブラリがあります。次の表に示すように、テーブルはすべてリストできません。読者がより良いクライアントFTPクラスライブラリを持っている場合は、さらにサプリメントを作成してください。
この記事では、著者はJ-FTPを採用しています。これはオープンソースであり、非常に強力なクライアントFTPライブラリです。著者はそれをとても気に入っており、すべての読者にもお勧めします。無料で忘れて、広告を出してください。
3。基本機能
1。ログインします
FTPはファイル転送に使用されますが、本質的に、java.net.socketは通信に使用されます。次のコードは、クラスnet.sf.jftp.net.ftpconnectionのログインメソッドの1つにすぎません。もちろん、レイアウトを保存し、次のコードでいくつかの原則を明確に説明するために、著者はログやその他のコードなどの不要なコードを削除しました。完全なコードについては、J-FTPのソースコードまたは著者の例のソースコードを参照してください。次のコードの例は同じです:
public int login(string username、string password){this.username = username; this.password = password; int status = login_ok; jcon = new jconnection(host、port); if(jcon.isthere()){in = jcon.getReader(); if(getline(position)== null)// ftp220_service_ready)== null){ok = false;ステータス=オフライン; } if(!getline(loginack).startswith(positive))// ftp230_logged_in)){if(success(success(positive))// ftp230_logged_in)){} els {ok = false; status =誤解_login_data; }}} else {if(msg){log.debug( "ftp not not abail!"); ok = false; status = generic_failed; }} if(ok){connected = true;システム();バイナリ(); string [] advsettings = new String [6]; if(getostype()。indexof( "os/2")> = 0){list_default = "list"; } if(list.equals( "default")){//最初の項目を取得するだけ(どういうわけか// ftpリストコマンドであることを知っています)advsettings = loadset.loadset(settings.adv_settings); // ***ファイルが見つからない場合は、それを作成してlist_defaultに設定します(advsettings == null){list = list_default; saveset s = new saveset(settings.adv_settings、list); } else {list = advsettings [0]; if(list == null){list = list_default; }}} if(getostype()。indexof( "mvs")> = 0){list = "list"; } // *** firedirectoryupdate(this); fireconnectionInitialized(this); } else {fireconnectionFailed(this、new Integer(status).toString()); }ステータスを返します。 }このログイン方法には、ソケットソケットの確立を担当するJConnectionクラスがあります。同時に、このクラスは別のスレッドです。利点は、インターフェイスの変更に協力するために、ネットワークソケット接続およびその他のタスクが個別のスレッドとして処理されることです。これは、インターフェイスの親しみやすさを助長します。以下は、net.sf.jftp.net.jconnectionクラスの実行方法です。もちろん、このスレッドの起動はJConnectionクラスのコンストラクターで開始されます。
public void run(){try {s = new Socket(host、port); localport = s.getlocalport(); // if(time> 0)s.setsotimeout(time); out = new PrintStream(new BufferedOutputStream(s.getOutputStream()、settings.BufferSize)); in = new BufferedReader(new inputStreamReader(s.getInputStream())、settings.BufferSize); isok = true; //}} catch(例外ex){ex.printstacktrace(); log.out( "警告:例外のために接続が閉じます(" + host + ":" + port + ")"); ISOK = false; try {if((s!= null)&&!s.isclosed()){s.close(); } if(out!= null){out.close(); } if(in!= null){in.close(); }} catch(Exception ex2){ex2.printstacktrace(); log.out( "警告:ソケットとストリームを閉じようとするエラーが増えました"); }}確立= true; }この実行方法のソケットは、2つのマシン間の通信エンドポイントであるクライアントソケット(「ソケット」とも呼ばれます)のこのタイプの実装をここで説明します。ソケットの実際の作業は、SocketImplクラスのインスタンスによって実行されます。アプリケーションは、ローカルファイアウォールに適したソケットを作成するように設定できるソケットファクトリを変更できるソケットを作成するソケットファクトリを実装します。特定の指示については、できれば中国語ではJDK5のAPI命令を参照してください。 hehe。
2アップロードしてダウンロードします
ファイルのアップロードは、マルチスレッドとシングルスレッドに分割できます。これは、単一スレッドの状況では比較的簡単ですが、マルチスレッドの状況では、処理すべきものが増え、より注意を払うことができます。以下は、net.sf.jftp.net.ftpconnectionのアップロードハンドループロードメソッドです。シングルスレッドとマルチスレッドの2つの異なるタイプが考慮されています。
public int handleupload(string file、string realname){if(settings.getEnableMultithReading()&&(!settings.getNouploadMultithReading())){log.out( "このアップロードの新しいスレッドの産卵"); ftptransfer t; if(realname!= null){t = new ftptransfer(host、port、getlocalpath()、getCachedPWD()、file、username、password、transfer.upload、ハンドラー、リスナー、RealName、crlf); } else {t = new ftptransfer(host、port、getlocalpath()、getCachedPWD()、file、username、password、transfor.upload、ハンドラー、リスナー、CRLF); } last transfer = t; new_transfer_spawnedを返します。 } else {if(settings.getnouploadmultithreading()){log.out( "upload multithreading is disabled。"); } else {log.out( "マルチスレッドは完全に無効になっています。"); } return(realname == null)? upload(file):upload(file、realname); }}マルチスレッドの場合、個別のクラスnet.sf.jftp.net.ftptransferがあります。もちろん、マルチスレッドの場合、このクラスは別のスレッドでなければなりません。 JConnectionと同様に、そのスレッドの起動もコンストラクターで開始されます。実行方法では、ファイルが読み取られて送信されます。
public void run(){if(handler.getConnections()。get(file)== null){handler.addconnection(file、this); } else if(!pause){log.debug( "既に進行中の転送:" + file); work = false; stat = 2;戻る; } boolean haspaused = false; while(一時停止){try {runner.sleep(100); if(リスナー!= null){for(int i = 0; i <ristens.size(); i ++){((connectionlistener)ristens.elementat(i))。 }} if(!work){if(ristens!= null){for(int i = 0; i <ristens.size(); i ++){((connectionlistener)ristens.elementat(i))。 }}}} catch(Exception ex){} haspaused = true; } while((handler.getConnectionSize()> = settings.getMaxConnections())&&(handler.getConnectionSize()> 0)&& work){try {stat = 4; runner.sleep(400); if(!haspause &&(risteners!= null)){for(int i = 0; i <ristens.size(); i ++){((connectionlistener)ristens.elementat(i))。 }} else {break; }} catch(Exception ex){ex.printstacktrace(); }} if(!work){if(ristens!= null){for(int i = 0; i <ristens.size(); i ++){((connectionlistener)ristens.elementat(i))。 }} Handler.RemoveConnection(file); stat = 3;戻る; } start = true; try {runner.sleep(settings.ftptransferthreadpause); } catch(Exception ex){} con = new ftpconnection(host、port、remotepath、crlf); con.setConnectionHandler(ハンドラー); con.setConnectionListeners(リスナー); int status = con.login(user、pass); if(status == ftpconnection.login_ok){file f = new file(localpath); con.setlocalpath(f.getabsolutepath()); if(type.equals(upload)){if(newname!= null){transferstatus = con.upload(file、newname); } else {transferstatus = con.upload(file); }} else {transferstatus = con.download(file、this.newname); }} if(!pause){handler.removeconnection(file); }}ダウンロードプロセスに関しては、アップロードの逆プロセスであるため、アップロード方法と書き込み方法に似ています。何らかの理由で、コードはリストされていませんが、そのアイデアとアイデアはまったく同じです。読者のソースコードを参照してください。
4。進行中のバー
アップロードまたはダウンロードプロセス中にプロンプトがない場合、ユーザーはタスクが完了したのか、タスクが死んでいるのかを判断できず、ユーザーがアップロード時間やダウンロード時間が長すぎるために誤解を招くことが多いことを想像できます。したがって、進行状況バーは非常に重要で実用的です。
Progress Barの実装は実際には非常に簡単です。プログラムに2つのスレッドを開くことです。最初のスレッドは、インターフェイス上の進行状況バーの値を動的に変更するために使用されますが、2番目のスレッドはアップロードまたはダウンロードプロセス中にループを形成します。このループでは、毎回8192バイトなどの特定の数のデータが読み取られます。次に、このデータを渡した後、最初のスレッドの更新プログレスメソッドを呼び出して、インターフェイスの進行状況バーの値を更新します。
アップロードまたはダウンロードプロセス(前のセクションのFTPTransferクラスの実行方法を参照)で、con.upload(file、newName)メソッドを表示できます。コードは次のとおりです。
public int upload(string file、string realname、inputstream in){hasuploaded = true; log.out( "ftp upload Started:" + this); int stat; if((in == null)&& new file(file).isdirectory()){shortProgress = true; filecount = 0; basefile = file; dataType = dataConnection.putdir; isdirupload = true; stat = uploaddir(file); shortprogress = false; //system.out.println(filecount + ":" + basefile); fireeprogressupdate(basefile、dataconnection.dfinished + ":" + filecount、-1); firealeactionfinished(this); firedirectoryupdate(this); } else {dataType = dataConnection.put; stat = rawupload(file、realname、in); {thread.sleep(100); } catch(Exception ex){} fireAcomtionFinished(this); firedirectoryupdate(this); } try {thread.sleep(500); } catch(Exception ex){} return stat; }この方法は、特定の数のバイトをアップロードする責任があります。実際、それはrawuploadメソッドと呼ばれます。ここにはリストされていません。ソースコードを参照してください。このバイトデータを渡した後、メインスレッドのupdateProgressBar()メソッドは、firealoctionFinished()メソッドを呼び出すことにより呼び出されます。実際、コードは次のとおりです。
保護されたvoid updateProgressBar(){intパーセント=(int)(((float)lfilecompletesize /(float)lfilesize) * 10000f); pbfile.setValue(パーセント); // system.out.println( "================================================================================================ pbfile.setString(lfilecompletesize / 1024l + " /" + lfilesize / 1024l + "kb");パーセント=(int)(((float)ltotalcompletesize /(float)ltotalsize) * 10000f); pbtotal.setString(ltotalcompletesize / 1024l + " /" + ltotalsize / 1024l + "kb"); pbtotal.setValue(パーセント); Repaint(); }上記で2つの進行状況バーが使用されています。最初の進捗バーは、現在のファイルのアップロードまたはダウンロードの進行状況を表し、Second Progress Barはすべてのファイルのダウンロードまたはアップロードの進行状況を表します。同時に、より明白な進行または進行状況の変化を生成するために、PBFILE.SESTMAXIMUM(10000)およびPBTOTAL.SESTMAXIMUM(10000)からPBFILE.SESTMAXIMUM(10000)を介して10,000に設定されます。著者は、アップロードまたはダウンロードするときに、ネットワークの理由により変更が比較的小さい場合があるため、これはより良いと考えています。 100に設定した場合、変更は特に明白ではありません。
上記は、FTPファイルの大きなバッチをアップロードしてダウンロードするための基本的な記事です。私はそれがすべての人の学習に役立つことを願っています、そして、私は誰もがwulin.comをもっとサポートすることを願っています。