تحميل ملف الخادم وتنزيله من خلال SSH
الكلمات المكتوبة في المقدمة
لقد قمت سابقًا بتسجيل طريقة لتحميل وتنزيل ملفات الخادم باستخدام مكون FTP Open Source من Apache ، لكن في وقت لاحق وجدت أنه سيكون هناك بعض مشاكل الإذن عند الحذف ، مما سيؤدي إلى عدم القدرة على حذف الملفات على الخادم. على الرغم من عدم وجود مشكلة بعد إعداد أذونات القراءة والكتابة باستخدام خادم Filezilla على Windows ، إلا أنه لا يزال من الصعب بعض الشيء استخدامها على جانب الخادم.
لأنني بحاجة إلى تنفيذ وظائف إدارة الموارد ، بالإضافة إلى تخزين FastDFS للملفات المفردة ، لا يزال من المقرر تخزين بعض تخزين موارد محددة مؤقتًا على الخادم. قال زملاء فريق المشروع إنهم لن يفتحوا خدمات FTP على وجه التحديد على الخادم لاحقًا ، لذلك تحولوا إلى SFTP للعمل.
كيفية استخدام هذا الشيء
أولاً ، تحتاج إلى تنزيل حزمة JSCH JAR ، العنوان هو: http://www.jcraft.com/jsch/. يكتب الموقع أيضًا بوضوح شديد: JSCH هو تطبيق Java خالص لـ SSH2. هذا هو تنفيذ جافا نقي لـ SSH2. استخدم IP والمنفذ ، وأدخل اسم المستخدم وكلمة المرور ويمكنك استخدامه بشكل طبيعي ، وهو نفس طريقة استخدام CRT الآمنة. فكيف تستخدم هذه الأداة المفيدة؟
في الواقع ، لا يهم إذا لم تتمكن من كتابتها. أعطى المسؤول أيضًا مثالاً. الرابط هو: http://www.jcraft.com/jsch/examples/shell.java. لنلقي نظرة:
/* -* -الوضع: Java ؛ C-basic refset: 2 ؛ adent-tabs-mode: nil-*-*// ***يمكّنك هذا البرنامج من الاتصال بخادم SSHD والحصول على موجه shell. * $ classpath =.: ../ build javac shell.java * $ classpath =.: ../ build java shell * سيُطلب منك اسم المستخدم ، اسم المضيف و passwd. * إذا كان كل شيء يعمل بشكل جيد ، فستحصل على موجه القشرة. قد يكون الإخراج * قبيحًا بسبب نقص التوليد الطرفي ، ولكن يمكنك إصدار أوامر. **/import com.jcraft.jsch.*؛ import java.awt.*؛ import javax.swing.*؛ shell shell {public static void main (string [] arg) {try {jsch jsch = new jsch () ؛ //jsch.setnownhosts (/يوم/foo/.ssh/nownlys_hosts ") ؛ مضيف سلسلة = فارغ ؛ if (arg.length> 0) {host = arg [0] ؛ } آخر {host = joptionpane.showInputDialog ("أدخل اسم username@hostname" ، system.getProperty ("user.name")+ "localhost") ؛ } string user = host.substring (0 ، host.indexof ('@')) ؛ مضيف = مضيف. جلسة الجلسة = jsch.getSession (المستخدم ، المضيف ، 22) ؛ String passwd = joptionpane.showInputDialog ("أدخل كلمة المرور") ؛ Session.setPassword (passwd) ؛ userInfo ui = new myuserinfo () {public void showmessage (string message) {joptionpane.showmessagedialog (null ، message) ؛ } boolean promptyesno (رسالة السلسلة) {Object [] chorse = {"yes" ، "no"} ؛ int foo = joptionpane.showoptiondialog (null ، message ، "تحذير" ، joptionpane.default_option ، joptionpane.warning_message ، null ، الخيارات ، الخيارات [0]) ؛ إرجاع foo == 0 ؛ } // إذا لم يتم إعطاء كلمة المرور قبل استدعاء الجلسة#connect () ، // تنفيذ أيضًا الطرق التالية ، // * userInfo#getPassword () ، // * userinfo#orderpassword (رسالة سلسلة) و // Session.setUserInfo (UI) ؛ // يجب عدم التوصية به ، ولكن إذا كنت ترغب في تخطي فحص مفتاح المضيف ، // استدعاء المتابعة ، // session.setConfig ("StricThostkeyChecking" ، "no") ؛ //session.connect () ؛ Session.connect (30000) ؛ // إجراء اتصال مع المهلة. Channel Channel = Session.OpenChannel ("shell") ؛ // تمكين الوكيل-تتبع. // (channelshell) Channel.SetInputStream (system.in) ؛ /* // مخترق لمطالبة MS-DOS على Windows. channel.setInputStream (new filterInputStream (system.in) {public int read (byte [] b ، int ، int len) يلقي ioException {return in.read (b ، Off ، (len> 1024؟ 1024: len)) ؛}}) ؛ */ channel.setOutputStream (system.out) ؛ /* // اختر النوع pty-type "VT102". ((channelshell) قناة) .SetPtyType ("VT102") ؛ * / /* // تعيين متغير البيئة "Lang" باسم "ja_jp.eucjp". ((channelshell) channel) .setenv ("lang" ، "ja_jp.eucjp") ؛ *///channel.connect () ؛ channel.connect (3*1000) ؛ } catch (استثناء e) {system.out.println (e) ؛ }} الفئة المجردة الثابتة العامة MyUserInfo تنفذ userinfo ، uikeyboardInterIntactive {public string getPassword () {return null ؛ } boolean promptyesno (String str) {return false ؛ } السلسلة العامة getPspSphRase () {return null ؛ ) ) } public void showMessage (رسالة سلسلة) {} السلسلة العامة [] repressKeyboardInterActive (الوجهة السلسلة ، اسم السلسلة ، تعليمات السلسلة ، السلسلة [] مطالبة ، Boolean [] echo) {return null ؛ }}}في هذا الرمز ، يمكننا أن نرى بشكل أساسي ما نحتاجه. أولاً ، نحتاج إلى إنشاء معلومات المستخدم. هذا يستخدم بشكل رئيسي للمصادقة. ما عليك سوى تنفيذ واجهتين لـ UserInfo و UikeYboardInterIntactive. ثم ، من خلال إنشاء جلسة جلسة ، قم بتعيين userinfo في ، واتصل أخيرًا.
تحميل الملفات المغلفة وتنزيلها
ما سبق هو طريقة الاستخدام الأساسية لـ JSCH ، أي بعض الروتينات الأساسية. دعنا نغلف الوظائف التي نريد استخدامها ، وتنفيذ سلسلة من العمليات مثل تحميل الملفات وتنزيلها.
أولاً ، قم بإنشاء userinfo:
الفئة العامة myuserInfo تنفذ userinfo ، uikeyboardInterActive {public string getPassword () {return null ؛ } boolean promptyesno (String str) {return true ؛ } السلسلة العامة getPspSphRase () {return null ؛ ) ) } public void showmessage (رسالة سلسلة) {} Override public string [] prompreyboybountive -actactive (String Arg0 ، string arg1 ، string arg2 ، string [] arg3 ، boolean [] arg4) {return null ؛ }}هنا فئة التنفيذ:
package com.tfxiaozi.common.Utils ؛ import java.io.inputstream ؛ import java.util.arraylist ؛ import java.util.iterator ؛ import java.util.list ؛ import java.util.vect com.jcraft.jsch.channelexec ؛ import com.jcraft.jsch.channelsftp ؛ import com.jcraft.jsch.jsch ؛ import com.jcraft.jsch.jschexception ؛ import com.jcraft.jsch.session com.jcraft.jsch.sftpprogrogressmonitor ؛/** * ssh utils * uuthor tfxiaozi * */public class ssh {logger logger = logger.getLogger (this.getClass ()) ؛ سلسلة الخاصة مضيف = "" ؛ user user user = "" ؛ منفذ int الخاص = 22 ؛ Private String Password = "" ؛ بروتوكول السلسلة النهائية الثابتة الخاصة = "SFTP" ؛ JSCH JSCH = New JSCH () ؛ جلسة خاصة ؛ قناة قناة خاصة ؛ القنوات الخاصة SFTP ؛ السلسلة العامة gethost () {return host ؛ } public void sethost (سلسلة مضيف) {this.host = host ؛ } السلسلة العامة getUser () {return user ؛ } public void setUser (string user) {this.user = user ؛ } public ssh () {} public ssh (مضيف سلسلة ، منفذ int ، مستخدم سلسلة ، كلمة مرور السلسلة) {this.host = host ؛ this.user = المستخدم ؛ this.password = كلمة المرور ؛ this.port = port ؛ } / ** * Connect Ssh * athrows jschexception * / public void connect () remrows jschexception {if (session == null) {session = jsch.getSession (user ، host ، port) ؛ myuserInfo ui = new myuserinfo () ؛ Session.setUserInfo (UI) ؛ Session.setPassword (كلمة المرور) ؛ Session.connect () ؛ القناة = session.openchannel (بروتوكول) ؛ channel.connect () ؛ قناة SFTP = (channelsftp) ؛ }} / ** * افصل ssh * / public void disconnect () {if (session! = null) {session.disconnect () ؛ الجلسة = فارغة ؛ }} / ** * upload * param localfilename * param remoteFiLename * regurn * / public boolean upload (String localFilename ، String RemoteFilename) يلقي الاستثناء {boolean bsucc = false ؛ حاول {sftpprogrogressMonitor Monitor = جديد myProgressMonitor () ؛ int mode = channelsftp.overwrite ؛ sftp.put (LocalFilename ، RemoteFilename ، Monitor ، Mode) ؛ BSUCC = صحيح ؛ } catch (استثناء e) {logger.error (e) ؛ } أخيرًا {if (null! = channel) {channel.disconnect () ؛ }} return bsucc ؛ } / ** * حذف الملف * param directory * param filename * return * / public boolean detectefile (string directory ، string filename) {boolean flag = false ؛ حاول {sftp.cd (دليل) ؛ sftp.rm (اسم الملف) ؛ العلم = صحيح ؛ } catch (sftpexception e) {flag = false ؛ logger.error (e) ؛ } العلم الإرجاع ؛ } / ** * حذف الدليل * param directory dir to be delete * param تأكد من حذف * @return * / public string deletedir (دليل السلسلة ، boolean sure) {string command = "rm -rf" + directory ؛ سلسلة السلسلة = execCommand (الأمر ، صحيح) ؛ نتيجة العودة }/** * اضغط على الملفات و sub-diR للدليل في zip compressname * param دليل المحتوى ليكون ضغط * param compressname الاسم في الدليل بعد مضغوط * throws sftpexception * usage ssh.compressdir ("/home/tfxiaozi/webapp" ، "test.zip") ؛ */public void compressDir (دليل السلسلة ، السلسلة CompressName) يلقي sftpexception {string command = "cd" + directory + "/nzip -r" + compressname + "./ execcommand (أمر ، صحيح) ؛ } / ** * تنزيل * param localfilename * param remoteFiLename * @RETURN * / public boolean download (String localFilename ، String RemoteFilename) {boolean bsucc = false ؛ قناة القناة = فارغة ؛ حاول {sftpprogrogressMonitor Monitor = جديد myProgressMonitor () ؛ sftp.get (RemoteFilename ، LocalFilename ، Monitor ، Channelsftp.Overwrite) ؛ BSUCC = صحيح ؛ } catch (استثناء e) {logger.error (e) ؛ } أخيرًا {if (null! = channel) {channel.disconnect () ؛ }} return bsucc ؛ } / ** * تنفيذ الأمر * param command * param flag * @return * / public string execcommand (command string ، boolean flag) {Channel Channel = null ؛ inputStream في = null ؛ StringBuffer SB = New StringBuffer ("") ؛ Try {Channel = Session.OpenChannel ("exec") ؛ System.out.println ("command:" + command) ؛ ((channelexec) قناة) .setCommand ("مصطلح التصدير = ANSI &&" + أمر) ؛ ((channelexec) قناة) .SeterRstream (system.err) ؛ في = channel.getInputStream () ؛ channel.connect () ؛ if (flag) {byte [] tmp = new byte [10240] ؛ بينما (صواب) {بينما (in.available ()> 0) {int i = in.read (tmp ، 0 ، 10240) ؛ if (i <0) {break ؛ } sb.append (سلسلة جديدة (tmp ، 0 ، i)) ؛ } if (channel.isclosed ()) {break ؛ }}} in.close () ؛ } catch (استثناء e) {logger.error (e) ؛ } أخيرًا {if (channel! = null) {channel.disconnect () ؛ }} return sb.toString () ؛ } / ** * الحصول على معلومات وحدة المعالجة المركزية * regurn * / public string [] getCpuinfo () {Channel Channel = null ؛ inputStream في = null ؛ StringBuffer SB = New StringBuffer ("") ؛ Try {Channel = Session.OpenChannel ("exec") ؛ ((channelexec) قناة) .SetCommand ("مصطلح التصدير = ANSI && TOP -BN 1") ؛ // يجب أن يضيف ANSI في = channel.getInputStream () ؛ ((channelexec) قناة) .SeterRstream (system.err) ؛ channel.connect () ؛ byte [] tmp = new byte [10240] ؛ بينما (صواب) {بينما (in.available ()> 0) {int i = in.read (tmp ، 0 ، 10240) ؛ if (i <0) {break ؛ } sb.append (سلسلة جديدة (tmp ، 0 ، i)) ؛ } if (channel.isclosed ()) {break ؛ }}} catch (استثناء e) {logger.error (e) ؛ } أخيرًا {if (channel! = null) {channel.disconnect () ؛ }} string buf = sb.toString () ؛ if (buf.indexof ("swap")! = -1) {buf = buf.substring (0 ، buf.indexof ("swap")) ؛ } if (buf.indexof ("CPU")! = -1) {buf = buf.substring (buf.indexof ("CPU") ، buf.length ()) ؛ } buf.replaceall ("" ، "") ؛ إرجاع buf.split ("// n") ؛ } / ** * احصل على معلومات القرص الثابت * @REGAN * / السلسلة العامة getharddiskinfo () رمي الاستثناء {Channel Channel = null ؛ inputStream في = null ؛ StringBuffer SB = New StringBuffer ("") ؛ Try {Channel = Session.OpenChannel ("exec") ؛ ((channelexec) قناة) .SetCommand ("df -lh") ؛ في = channel.getInputStream () ؛ ((channelexec) قناة) .SeterRstream (system.err) ؛ channel.connect () ؛ byte [] tmp = new byte [10240] ؛ بينما (صواب) {بينما (in.available ()> 0) {int i = in.read (tmp ، 0 ، 10240) ؛ if (i <0) {break ؛ } sb.append (سلسلة جديدة (tmp ، 0 ، i)) ؛ } if (channel.isclosed ()) {break ؛ }}} catch (استثناء e) {رمي new runTimeException (e) ؛ } أخيرًا {if (channel! = null) {channel.disconnect () ؛ }} string buf = sb.toString () ؛ string [] info = buf.split ("/n") ؛ if (info.length> 2) {// first line: حجم ملفات الملفات المستخدمة الاستفادة استخدام ٪ مثبتة على السلسلة tmp = "" ؛ لـ (int i = 1 ؛ i <info.length ؛ i ++) {tmp = info [i] ؛ String [] tmparr = tmp.split ("٪") ؛ if (tmparr [1] .trim (). يساوي ("/")) {boolean flag = true ؛ بينما (flag) {tmp = tmp.replaceall ("" ، "") ؛ if (tmp.indexof ("") == -1) {flag = false ؛ }} string [] result = tmp.split ("") ؛ if (result! = null && result.length == 6) {buf = result [1] + "total ،" + result [2] + "use ،" + result [3] + "free" ؛ استراحة؛ } آخر {buf = "" ؛ }}}} آخر {buf = "" ؛ } إرجاع buf ؛ } / ** * إرجاع عدد البايتات المجانية * regurn * throws استثناء * / public double getFreedisk () رمي الاستثناء {String harddiskinfo = getharddiskinfo () ؛ if (harddiskinfo == null || harddiskinfo.equals ("")) {logger.Error ("الحصول على مساحة مجانية fray space ......") ؛ العودة -1 ؛ } string [] diskinfo = harddiskinfo.replace ("" ، "") .Split ("،") ؛ if (diskinfo == null || diskinfo.length == 0) {logger.error ("فشل الحصول على معلومات القرص المجانية ......") ؛ العودة -1 ؛ } سلسلة مجانية = diskinfo [2] ؛ free = free.substring (0 ، free.indexof ("free")) ؛ //system.out.println("free space: " + free) ؛ وحدة السلسلة = free.substring (free.length ()-1) ؛ //system.out.println("unit: " + unit) ؛ String freespace = free.substring (0 ، free.length ()-1) ؛ مزدوج freespacel = double.parsedouble (freespace) ؛ //system.out.println("free spacel: " + freespacel) ؛ if (unit.equals ("k")) {return freespacel*1024 ؛ } آخر إذا (unit.equals ("m")) {return freespacel*1024*1024 ؛ } آخر إذا (unit.equals ("g")) {return freespacel*1024*1024*1024 ؛ } if if (unit.equals ("t")) {return freespacel*1024*1024*1024*1024 ؛ } if if (unit.equals ("p")) {return freespacel*1024*1024*1024*1024 ؛ } العودة 0 ؛ } / ** * احصل على جميع الدليل الفرعي والملفات في الدليل المحدد * param دليل * regurn * throws استثناء * / suppressWarnings ("RawTypes") القائمة العامة <string> listFiles (دليل السلسلة) استثناء {vector filelist = null ؛ قائمة <Tring> fileNamelist = new ArrayList <String> () ؛ fileList = sftp.ls (دليل) ؛ iterator it = fileList.iterator () ؛ بينما (it.hasnext ()) {سلسلة filename = ((channelsftp.lsentry) it.next ()). getFilename () ؛ if (filename.startswith (".") || filename.StartSwith ("..")) {extree ؛ } filenamelist.add (اسم الملف) ؛ } عودة FileNamelist ؛ } Boolean Mkdir (مسار السلسلة) {flag boolean = false ؛ حاول {sftp.mkdir (path) ؛ العلم = صحيح ؛ } catch (sftpexception e) {flag = false ؛ } العلم الإرجاع ؛ }}اختباره
يرمي الفراغ الثابت العام (سلسلة [] arg) استثناء {ssh ssh = new ssh ("10.10.10.83" ، 22 ، "test" ، "test") ؛ حاول {ssh.connect () ؛ } catch (jschexception e) {e.printStackTrace () ؛ }/*string remotepath = "/home/tfxiaozi/" + "webapp/" ؛ حاول {ssh.listfiles (remotepath) ؛ } catch (استثناء e) {ssh.mkdir (remotepath) ؛ }*//*boolean b = ssh.upload ("d: /test.zip" ، "webapp/") ؛ system.out.println (b) ؛*/// string [] buf = ssh.getCpuinfo () ؛ //system.out.println("cpu: " + buf [0]) ؛ //system.out.println("memo: " + buf [1]) ؛ //system.out.println(Ssh.GethardDiskinfo (). استبدال ("" ، "")) ؛ //system.out.println (ssh.getFreedisk ()) ؛ /*list <String> list = ssh.listfiles ("webapp/test") ؛ لـ (String s: list) {system.out.println (s) ؛ }* / /*boolean b = ssh.detelefile ("webapp" ، "test.zip") ؛ system.out.println (b) ؛*//*try {string s = ssh.execcommand ("ls -l/home/tfxiaozi/webapp1/test" ، true) ؛ system.out.println (s) ؛ } catch (استثناء e) {system.out.println (e.getMessage ()) ؛ }*///ssh.sftp.setfilenameencoding("utf-8 ") ؛ /*حاول {string ss = ssh.execcommand ("unsip /home/tfxiaozi/webapp1/test.zip -d/home/tfxiaozi/webapp1/" ، true) ؛ System.out.println (SS) ؛ } catch (استثناء e) {system.out.println (e.getMessage ()) ؛ }*//*string path = "/home/tfxiaozi/webapp1/test.zip" ؛ حاول {list <string> list = ssh.listfiles (path) ؛ لـ (String s: list) {system.out.println (s) ؛ } system.out.println ("ok") ؛ } catch (استثناء e) {system.out.println ("فشل الاستخراج ....") ؛ }*//*string command = "rm -rf/home/tfxiaozi/webapp1/" + "الحبر وغسل الدراسات الصينية" ؛ سلسلة sss = ssh.execcommand (الأمر ، صحيح) ؛ System.out.println (SSS) ؛*//*string findCommand = "Find/Home/Tfxiaozi/WebApp1/الحبر وغسل الدراسات الصينية". String result = ssh.execCommand (findCommand ، true) ؛ system.out.println (result) ؛* / /*string path = "" ؛ ssh.listfiles (remotepath) ؛*//* ssh.deletedir ("/home/tfxiaozi/webapp1" ، true) ؛ *//سيتم إلغاء ضغط ما يلي إلى دليل webapp1 ، webapp1/test/xxx //ssh.execcommand("unzip /home/tfxiaozi/webapp1/test.zip -d/home/tfxiaozi/webapp1 "، صحيح) ؛ // سيتم إلغاء ضغط ما يلي إلى/webapp1/test/test/xxx //ssh.execcommand("unzip /home/tfxiaozi/webapp1/test.zip -d/home/tfxiaozi/webapp1 "، صحيح) ؛ //ssh.compressdir("/home/tfxiaozi/webapp1 "،" test.zip ") ؛ //ssh.sftp.cd("/home/tfxiaozi/webapp1 ") ؛ //ssh.compressdir("/home/tfxiaozi/webapp1 "،" test.zip ") ؛ /*boolean b = ssh.download ("d: /temp/test.zip" ، "webapp/test.zip") ؛ system.out.println (b) ؛*///ssh.getharddiskinfo () ؛ system.out.println (ssh.getFreedisk ()) ؛ ssh.Disconnect () ؛ } ما سبق هو استخدام Linux للعمل مباشرة ، ولكن تجدر الإشارة إلى أنه بالنسبة للملفات الصينية ، عند إلغاء الضغط ، قد يكون هناك رمز مشتعل عند المرور ، ويجب إضافة المعلمات ، مثل unsip -o cp936 test.zip -d/home/tfxiaozi/test.
ما سبق هو كل محتوى هذه المقالة. آمل أن يكون ذلك مفيدًا لتعلم الجميع وآمل أن يدعم الجميع wulin.com أكثر.