Artikel ini memperkenalkan cara menggunakan perpustakaan yang tersedia yang ada di Java untuk menulis kode klien FTP dan mengembangkannya ke kontrol applet untuk membuat batch, file besar mengunggah dan mengunduh kontrol berdasarkan web. Berdasarkan serangkaian perpustakaan pelanggan FTP, artikel ini memberikan penjelasan terperinci dan implementasi kode pada salah satu perpustakaan J-FTP yang lebih umum dan kuat, seperti bilah kemajuan, kelanjutan breakpoint, pemetaan jaringan internal dan eksternal, dan fungsi javascript panggilan balik di applet. Diharapkan bahwa artikel ini akan berperan dalam menarik batu giok.
1. Pendahuluan
Selama implementasi suatu proyek, unggahan file dan persyaratan unduhan berbasis web telah muncul. Pengguna di seluruh provinsi (atau nasional) perlu mengunggah beberapa file ke server file di pusat tertentu. Dokumen-dokumen ini digunakan untuk beberapa konstruksi teknik skala besar, yang mungkin melibatkan proyek konstruksi senilai puluhan juta atau bahkan ratusan juta yuan. File memiliki tiga karakteristik yang berbeda: satu adalah bahwa file tersebut besar, yang dapat mencapai 50m; Yang kedua adalah bahwa jumlah file besar, yang mungkin sekitar 15; Yang ketiga adalah bahwa tanda tangan digital dan enkripsi data diperlukan dalam hal keamanan data.
Pertama-tama, pertimbangkan metode transmisi berbasis HTTP. Namun, melalui perbandingan, saya dengan cepat menemukan bahwa kebutuhan di atas dipenuhi:
1: Mengunggah menggunakan protokol HTTP tampaknya lebih cocok untuk kenyamanan pemrograman web; Mengunggah file kurang dari 1m sedikit lebih cepat daripada mengunggah file menggunakan protokol FTP. Tetapi mungkin tidak ada yang bisa dilakukan tentang transfer batch dan file besar. Tentu saja, ia juga memiliki kelebihan, seperti tidak seperti FTP, perlu untuk memulai layanan FTP di sisi server.
2: Mengunggah file dengan file yang lebih besar dari 1m menggunakan protokol FTP lebih cepat dari HTTP. Semakin besar file, kecepatan unggah akan beberapa kali lebih cepat dari kecepatan unggah HTTP. Dan menulis program di Java; FTP lebih nyaman daripada HTTP.
Penulis pernah menggunakan VB dan menulis kontrol ActiveX untuk mengunggah dan mengunduh file batch, dan fungsinya juga sangat kuat. Hanya karena tidak ada tanda tangan digital khusus untuk file CAB atau OCX, perlu untuk melakukan pengaturan yang membosankan untuk klien, seperti menyiapkan situs yang aman, mengurangi tingkat keamanan klien, dll., Beberapa solusi telah ditinggalkan.
Pada saat yang sama, mengingat file -file tersebut perlu ditandatangani secara digital dan dienkripsi pada klien, diputuskan untuk menggunakan applet untuk mengimplementasikannya. . Sebelum mengunggah file, informasi kunci USBKEY lokal dapat diperoleh dari klien untuk menyelesaikan enkripsi dan pemrosesan tanda tangan dari file yang diunggah. Meskipun menggunakan Applet memerlukan pemasangan lingkungan runtime JRE pada klien, yang membawa ketidaknyamanan pada manajemen dan penggunaan klien, mungkin harga yang relatif kecil untuk membandingkan keamanan sejumlah besar file dan file.
Untuk meringkas lingkungan operasi:
Sisi Server FTP: Serv-U, program sisi server FTP profesional, ada unduhan perangkat lunak siap pakai di Internet, tentu saja pembaca juga dapat menulis program penerima file FTP sisi server untuk dijelaskan. Jika tidak ada persyaratan atau fungsi khusus, Serv-U harus dapat memenuhi kebutuhan unggahan dan unduhan umum kami;
Klien: Java Applet, sebuah teknologi yang membuat Java populer kemudian mengaku sebanding dengan Microsoft's ActiveX. Tentu saja, sekarang Java memiliki Java FX. Apakah ini pengganti applet?
Lingkungan Aplikasi: Internet, tujuan akhir.
2. Pilihan Perpustakaan Klien Java FTP
Mari kita bayangkan sebuah skenario - kami ingin menulis aplikasi Java murni yang mengunggah dan mengunduh file dari server FTP yang berjalan di komputer jarak jauh; Kami juga ingin mendapatkan informasi file dasar untuk file jarak jauh tersebut untuk diunduh, seperti nama file, data atau ukuran file.
Meskipun mungkin dan mungkin menarik untuk menulis penangan protokol FTP dari awal, pekerjaannya juga sulit, panjang dan berpotensi berbahaya. Karena kita tidak mau menghabiskan waktu, energi, atau uang untuk menulis program pemrosesan seperti itu sendiri, kita beralih ke komponen yang dapat digunakan kembali yang sudah ada. Dan banyak perpustakaan tersedia secara online.
Menemukan Perpustakaan Klien Java FTP yang sangat baik yang sesuai dengan kebutuhan kita tidak sesederhana kelihatannya. Sebaliknya, ini adalah tugas yang sangat menyakitkan dan rumit. Pertama, butuh waktu untuk menemukan perpustakaan klien FTP. Kedua, setelah kita menemukan semua perpustakaan yang ada, mana yang harus kita pilih? Setiap perpustakaan cocok untuk kebutuhan yang berbeda. Perpustakaan ini tidak setara dalam kinerja dan memiliki perbedaan mendasar dalam desainnya. Setiap perpustakaan memiliki karakteristiknya sendiri dan menggunakan istilah yang berbeda untuk menggambarkannya. Oleh karena itu, mengevaluasi dan membandingkan pustaka klien FTP adalah tugas yang sulit.
Menggunakan komponen yang dapat digunakan kembali adalah pendekatan yang diadvokasi, tetapi dalam hal ini sering mengecewakan pada awalnya. Kemudian, saya mungkin sedikit malu: Setelah memilih perpustakaan FTP yang baik, karya selanjutnya sangat sederhana, cukup ikuti aturan sederhana. Saat ini, ada banyak perpustakaan klien FTP publik dan gratis, seperti SimpleFTP, J-FTP, dll., Dan banyak klien FTP lainnya. Seperti yang ditunjukkan pada tabel berikut, tabel tidak dapat terdaftar semua. Jika pembaca memiliki perpustakaan kelas FTP klien yang lebih baik, silakan buat suplemen lebih lanjut.
Dalam artikel ini, penulis mengadopsi J-FTP. Ini adalah sumber terbuka dan perpustakaan FTP klien yang sangat kuat. Penulis sangat menyukainya, dan juga merekomendasikannya kepada semua pembaca. Lupakan secara gratis dan buat iklan untuk itu.
3. Fungsi Dasar
1. Masuk
FTP digunakan untuk transfer file, tetapi pada dasarnya, java.net.socket digunakan untuk komunikasi. Kode berikut hanyalah salah satu metode login dari kelas net.sf.jftp.net.ftpconnection. Tentu saja, untuk menyimpan tata letak dan menjelaskan beberapa prinsip dengan jelas dalam kode berikut, penulis telah menghapus beberapa kode yang tidak perlu, seperti log dan kode lainnya. Untuk kode lengkap, silakan merujuk ke kode sumber J-FTP atau kode sumber contoh penulis. Contoh kode berikut adalah sama:
Public Int Login (String UserName, String Password) {this.userName = userName; this.password = kata sandi; status int = login_ok; jcon = JConnection baru (host, port); if (jcon.isThere ()) {in = jcon.getreader (); if (getline (positif) == null) // ftp220_service_ready) == null) {ok = false; status = offline; } if (! getline (loginack) .startswith (positif)) // ftp230_logged_in)) {if (sukses (positif)) // ftp230_logged_in)) {} else {ok = false; status = salah_login_data; }}} else {if (msg) {log.debug ("ftp tidak tersedia!"); ok = false; status = generic_failed; }} if (ok) {connected = true; sistem(); biner (); String [] advSettings = string baru [6]; if (getoStype (). indexOf ("os/2")> = 0) {list_default = "list"; } if (list.equals ("default")) {// cukup dapatkan item pertama (entah bagaimana diketahui pertama adalah perintah // ftp list) advSettings = loadset.loadset (settings.adv_settings); // *** Jika file tidak ditemukan, buat dan atur ke list_default if (advSettings == null) {list = list_default; SaveSet s = saveSet baru (settings.adv_settings, list); } else {list = advSettings [0]; if (list == null) {list = list_default; }}} if (getoStype (). indexOf ("mvs")> = 0) {list = "list"; } // *** firedirectoryupdate (ini); fireconnectioninitialisasi (ini); } else {fireconnectionFailed (this, new integer (status) .toString ()); } status pengembalian; } Dalam metode login ini, ada kelas JConnection, yang bertanggung jawab untuk membuat soket soket. Pada saat yang sama, kelas ini adalah utas terpisah. Keuntungannya adalah untuk bekerja sama dengan perubahan antarmuka, koneksi soket jaringan dan tugas -tugas lain diproses sebagai utas terpisah, yang kondusif untuk keramahan antarmuka. Di bawah ini adalah metode run dari kelas net.sf.jftp.net.jconnection. Tentu saja, startup utas ini dimulai pada konstruktor kelas JConnection.
public void run () {coba {s = soket baru (host, port); localport = s.getLocalport (); // if (time> 0) s.setsoTimeout (waktu); out = printStream baru (baru bufferedoutputStream (s.getoutputStream (), settings.bufferSize)); di = BufferedReader baru (inputStreamReader baru (s.getInputStream ()), settings.bufferSize); isok = true; //}} catch (exception ex) {ex.printstacktrace (); Log.out ("peringatan: koneksi ditutup karena pengecualian (" + host + ":" + port + ")"); isok = false; coba {if ((s! = null) &&! s.isclosed ()) {s.close (); } if (out! = null) {out.close (); } if (in! = null) {in.close (); }} catch (Exception ex2) {ex2.printstacktrace (); Log.out ("peringatan: mendapat lebih banyak kesalahan yang mencoba menutup soket dan stream"); }} dibangun = true; }Soket dalam metode run ini akan menjelaskan di sini bahwa jenis implementasi soket klien ini (juga disebut "soket"), yang merupakan titik akhir komunikasi antara dua mesin. Pekerjaan soket yang sebenarnya dilakukan oleh contoh kelas SocketImpl. Aplikasi mengimplementasikan pabrik soket yang membuat soket dengan mengubah pabrik soket yang dapat mengonfigurasi dirinya untuk membuat soket yang cocok untuk firewall lokal. Untuk instruksi khusus, silakan merujuk ke instruksi API JDK5, lebih disukai dalam bahasa Cina. hehe.
2 Unggah dan unduh
Mengunggah file dapat dibagi menjadi multi-threaded dan utas tunggal, yang relatif sederhana dalam situasi tunggal, sementara dalam situasi multi-threaded, lebih banyak hal yang harus ditangani dan lebih hati-hati. Di bawah ini adalah metode unggahan handleupload dari net.sf.jftp.net.ftpconnection. Dua jenis yang berbeda, utas tunggal dan multi-thread, telah dipertimbangkan.
public int handleupload (file string, string realname) {if (settings.geteNableMultithreading () && (! settings.getNouploadMultithReading ())) {log.out ("Memalukan utas baru untuk unggahan ini."); Ftptransfer t; if (realname! = null) {t = ftptransfer baru (host, port, getLocalPath (), getCachedpwd (), file, nama pengguna, kata sandi, transfer.upload, pawang, pendengar, realname, crlf); } else {t = ftptransfer baru (host, port, getLocalPath (), getCachedpwd (), file, nama pengguna, kata sandi, transfer.upload, pawang, pendengar, crlf); } lastTransfer = t; return new_transfer_spawned; } else {if (settings.getNouploadMultithReading ()) {log.out ("Unggah multithreading dinonaktifkan."); } else {log.out ("Multithreading sepenuhnya dinonaktifkan."); } return (realName == null)? unggah (file): unggah (file, realname); }} Dalam kasus multi-threading, ada kelas terpisah net.sf.jftp.net.ftptransfer. Tentu saja, dalam kasus multi-threading, kelas ini harus berupa utas terpisah. Mirip dengan JConnection, startup utasnya juga dimulai pada konstruktor. Dalam metode yang dijalankan, file dibaca dan dikirim.
public void run () {if (handler.getConnections (). get (file) == null) {handler.addconnection (file, this); } else if (! jeda) {log.debug ("Transfer sudah berlangsung:" + file); Work = false; stat = 2; kembali; } boolean haspaused = false; while (jeda) {coba {runner.sleep (100); if (listeners! = null) {for (int i = 0; i <listeners.size (); i ++) {((connectionListener) listeners.elementat (i)). updateProgress (file, berhenti, -1); }} if (! Work) {if (listeners! = null) {for (int i = 0; i <listeners.size (); i ++) {((ConnectionListener) listeners.elementat (i)). UpdateProgress (file, dihapus, -1); }}}} catch (Exception ex) {} haspaSeused = true; } while ((handler.getConnectionSize ()> = settings.getmaxConnections ()) && (handler.getConnectize ()> 0) && work) {coba {stat = 4; runner.sleep (400); if (! haspaSe && (pendengar! = null)) {for (int i = 0; i <listeners.size (); i ++) {((ConnectionListener) listeners.elementat (i)). UpdateProgress (file, antrian, -1); }} else {break; }} catch (exception ex) {ex.printstacktrace (); }} if (! Work) {if (listeners! = null) {for (int i = 0; i <listeners.size (); i ++) {((ConnectionListener) listeners.elementat (i)). UpdateProgress (file, dihapus, -1); }} handler.removeconnection (file); stat = 3; kembali; } dimulai = true; coba {runner.sleep (settings.ftptransferThreadpaSe); } catch (Exception ex) {} con = ftpConnection baru (host, port, remotePath, crlf); con.setConnectionHandler (Handler); con.setConnectionListeners (pendengar); status int = con.login (pengguna, pass); if (status == ftpconnection.login_ok) {file f = file baru (localpath); con.setlocalpath (f.getAbsolutePath ()); if (type.equals (unggah)) {if (newName! = null) {transferstatus = con.upload (file, newname); } else {transfererstatus = con.upload (file); }} else {transfererstatus = con.download (file, this.newName); }} if (! Pause) {handler.removeconnection (file); }} Sedangkan untuk proses pengunduhan, karena ini adalah proses pengunggahan terbalik, ini mirip dengan metode unggahan dan metode penulisan. Untuk beberapa alasan, kode tidak terdaftar, tetapi ide dan idenya persis sama. Silakan merujuk ke kode sumber untuk pembaca.
4. Bar Kemajuan
Dapat dibayangkan bahwa jika tidak ada prompt selama proses unggahan atau unduhan, pengguna tidak dapat menilai apakah tugas selesai atau apakah tugas sudah mati, dan pengguna sering menyesatkan karena waktu unggahan atau waktu pengunduhan terlalu lama. Oleh karena itu, bilah kemajuan sangat penting dan praktis.
Implementasi bilah kemajuan sebenarnya sangat sederhana. Ini untuk membuka dua utas dalam program. Utas pertama digunakan untuk secara dinamis mengubah nilai bilah kemajuan pada antarmuka, sedangkan utas kedua membentuk loop selama proses unggahan atau unduhan. Dalam loop ini, sejumlah data seperti 8192 byte dibaca setiap kali. Kemudian setelah menyampaikan data ini, hubungi metode UpdateProgress di utas pertama untuk memperbarui nilai bilah progres antarmuka.
Selama proses unggahan atau unduhan (lihat metode run dari kelas FTPTransfer di bagian sebelumnya), Anda dapat melihat metode con.upload (file, newname), kodenya adalah sebagai berikut.
unggah int int (file string, string realname, inputStream in) {hasuploaded = true; Log.out ("Upload FTP dimulai:" + ini); int stat; if ((in == null) && baru file (file) .isDirectory ()) {shortprogress = true; filecount = 0; BASEFILE = file; DataType = DataConnection.putDir; isDirUpload = true; stat = unggahdir (file); shortprogress = false; //System.out.println(fileCount + ":" + Basefile); FireProgressUpdate (Basefile, DataConnection.Dfinished + ":" + FileCount, -1); fireactionfinished (ini); firedirectoryupdate (ini); } else {DataType = DataConnection.put; stat = rawupload (file, realname, in); coba {thread.sleep (100); } catch (exception ex) {} fireactionfinished (this); firedirectoryupdate (ini); } coba {thread.sleep (500); } catch (Exception ex) {} return stat; }Metode ini bertanggung jawab untuk mengunggah sejumlah byte tertentu. Bahkan, itu disebut metode Rawupload. Itu tidak terdaftar di sini. Silakan merujuk ke kode sumber. Setelah menyampaikan data byte ini, metode UpdateProgressBar () di utas utama dipanggil dengan memanggil metode fireactionfinished (). Sebenarnya kodenya adalah sebagai berikut:
void updateProgressBar () yang dilindungi (int persen = (int) (((float) lfileCompleteSize / (float) lfileSize) * 10000f); pbfile.setValue (persen); // System.out.println ("====================================================="+persen); pbfile.setstring (lfileCompletesize / 1024l + " /" + lfilesize / 1024l + "kb"); persen = (int) (((float) ltotalCompletesize / (float) ltotalsize) * 10000f); pBtotal.setstring (ltotalCompletesize / 1024l + " /" + ltotalSize / 1024l + "kb"); pBtotal.setValue (persen); ulang (); } Dua batang kemajuan digunakan di atas. Bilah kemajuan pertama mewakili unggahan atau unduhan kemajuan file saat ini, dan bilah kemajuan kedua mewakili kemajuan semua file unduhan atau unggah. Pada saat yang sama, untuk menghasilkan perkembangan atau perubahan kemajuan yang lebih jelas, nilai maksimum bilah kemajuan diatur ke 10.000 melalui pbfile.setMaximum (10000) dan pBtotal.setMaximum (10000), daripada 100 yang biasanya kami setel. Penulis percaya bahwa ini lebih baik, karena kadang -kadang ketika mengunggah atau mengunduh, perubahan mungkin relatif kecil karena alasan jaringan. Jika diatur ke 100, perubahannya tidak terlalu jelas.
Di atas adalah artikel dasar untuk mengunggah dan mengunduh sejumlah besar file FTP. Saya berharap ini akan membantu untuk pembelajaran semua orang, dan saya harap semua orang akan lebih mendukung wulin.com.