国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

JSch

2019-11-15 00:14:21
字體:
來源:轉載
供稿:網友
JSch - java實現的SFTP(文件上傳詳解篇) [轉載]

文章來源:http://m.survivalescaperooms.com/longyg/archive/2012/06/25/2556576.html

JSch是Java Secure Channel的縮寫。JSch是一個SSH2的純Java實現。它允許你連接到一個SSH服務器,并且可以使用端口轉發,X11轉發,文件傳輸等,當然你也可以集成它的功能到你自己的應用程序。

本文只介紹如何使用JSch實現的SFTP功能。SFTP是Secure File Transfer PRotocol的縮寫,安全文件傳送協議。可以為傳輸文件提供一種安全的加密方法。SFTP 為 SSH的一部份,是一種傳輸文件到服務器的安全方式。SFTP是使用加密傳輸認證信息和傳輸的數據,所以,使用SFTP是非常安全的。但是,由于這種傳輸方式使用了加密/解密技術,所以傳輸效率比普通的FTP要低得多,如果您對網絡安全性要求更高時,可以使用SFTP代替FTP。(來自百度的解釋)要使用JSch,需要下載它的jar包,請從官網下載它:http://www.jcraft.com/jsch/ChannelSftp類是JSch實現SFTP核心類,它包含了所有SFTP的方法,如:put(): 文件上傳get(): 文件下載cd(): 進入指定目錄ls():得到指定目錄下的文件列表rename(): 重命名指定文件或目錄rm(): 刪除指定文件mkdir(): 創建目錄rmdir(): 刪除目錄等等(這里省略了方法的參數,put和get都有多個重載方法,具體請看源代碼,這里不一一列出。)JSch支持三種文件傳輸模式:
OVERWRITE完全覆蓋模式,這是JSch的默認文件傳輸模式,即如果目標文件已經存在,傳輸的文件將完全覆蓋目標文件,產生新的文件。
RESUME

恢復模式,如果文件已經傳輸一部分,這時由于網絡或其他任何原因導致文件傳輸中斷,如果下一次傳輸相同的文件,

則會從上一次中斷的地方續傳。

APPEND追加模式,如果目標文件已存在,傳輸的文件將在目標文件后追加。

創建ChannelSftp對象

編寫一個工具類,根據ip,用戶名及密碼得到一個SFTP channel對象,即ChannelSftp的實例對象,在應用程序中就可以使用該對象來調用SFTP的各種操作方法。

SFTPChannel.java按 Ctrl+C 復制代碼按 Ctrl+C 復制代碼

SFTPConstants是一個靜態成員變量類:

SFTPConstans.java按 Ctrl+C 復制代碼按 Ctrl+C 復制代碼

文件上傳

實現文件上傳可以調用ChannelSftp對象的put方法。ChannelSftp中有12個put方法的重載方法:

public void put(String src, String dst)

將本地文件名為src的文件上傳到目標服務器,目標文件名為dst,若dst為目錄,則目標文件名將與src文件名相同。

采用默認的傳輸模式:OVERWRITE

public void put(String src, String dst, int mode)

將本地文件名為src的文件上傳到目標服務器,目標文件名為dst,若dst為目錄,則目標文件名將與src文件名相同。

指定文件傳輸模式為mode(mode可選值為:ChannelSftp.OVERWRITE,ChannelSftp.RESUME,

ChannelSftp.APPEND)

public void put(String src, String dst, SftpProgressMonitor monitor)

將本地文件名為src的文件上傳到目標服務器,目標文件名為dst,若dst為目錄,則目標文件名將與src文件名相同。

采用默認的傳輸模式:OVERWRITE

并使用實現了SftpProgressMonitor接口的monitor對象來監控文件傳輸的進度。

public void put(String src, String dst, SftpProgressMonitor monitor, int mode)

將本地文件名為src的文件上傳到目標服務器,目標文件名為dst,若dst為目錄,則目標文件名將與src文件名相同。

指定傳輸模式為mode

并使用實現了SftpProgressMonitor接口的monitor對象來監控文件傳輸的進度。

public void put(InputStream src, String dst)

將本地的input stream對象src上傳到目標服務器,目標文件名為dst,dst不能為目錄。

采用默認的傳輸模式:OVERWRITE

public void put(InputStream src, String dst, int mode)

將本地的input stream對象src上傳到目標服務器,目標文件名為dst,dst不能為目錄。

指定文件傳輸模式為mode

public void put(InputStream src, String dst, SftpProgressMonitor monitor)

將本地的input stream對象src上傳到目標服務器,目標文件名為dst,dst不能為目錄。

采用默認的傳輸模式:OVERWRITE

并使用實現了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

public void put(InputStream src, String dst, SftpProgressMonitor monitor, int mode)

將本地的input stream對象src上傳到目標服務器,目標文件名為dst,dst不能為目錄。

指定文件傳輸模式為mode

并使用實現了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

public OutputStream put(String dst)

該方法返回一個輸出流,可以向該輸出流中寫入數據,最終將數據傳輸到目標服務器,目標文件名為dst,dst不能為目錄。

采用默認的傳輸模式:OVERWRITE

public OutputStream put(String dst, final int mode)

該方法返回一個輸出流,可以向該輸出流中寫入數據,最終將數據傳輸到目標服務器,目標文件名為dst,dst不能為目錄。

指定文件傳輸模式為mode

public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode)

該方法返回一個輸出流,可以向該輸出流中寫入數據,最終將數據傳輸到目標服務器,目標文件名為dst,dst不能為目錄。

指定文件傳輸模式為mode

并使用實現了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

public OutputStream put(String dst, final SftpProgressMonitor monitor, final int mode, long offset)

該方法返回一個輸出流,可以向該輸出流中寫入數據,最終將數據傳輸到目標服務器,目標文件名為dst,dst不能為目錄。

指定文件傳輸模式為mode

并使用實現了SftpProgressMonitor接口的monitor對象來監控傳輸的進度。

offset指定了一個偏移量,從輸出流偏移offset開始寫入數據。

應用實例:

SFTPTest.java

按 Ctrl+C 復制代碼按 Ctrl+C 復制代碼

:請分別將代碼段1,代碼段2,代碼段3取消注釋,運行程序來進行測試。這三段代碼分別演示了如何使用JSch的不同的put方法來進行文件上傳。

代碼段1:采用向put方法返回的輸出流中寫入數據的方式來傳輸文件。需要由程序來決定寫入什么樣的數據,這里是將本地文件的輸入流寫入輸出流。采用這種方式的好處是,可以自行設定每次寫入輸出流的數據塊大小,如本示例中的語句:

byte[] buff = new byte[1024 * 256]; // 設定每次傳輸的數據塊大小為256KB

代碼段2:直接將本地文件名為src的文件上傳到目標服務器,目標文件名為dst。(注:使用這個方法時,dst可以是目錄,當dst是目錄時,上傳后的目標文件名將與src文件名相同)

代碼段3:將本地文件名為src的文件輸入流上傳到目標服務器,目標文件名為dst。

這三段代碼實現的功能是一樣的,都是將本地的文件src上傳到了服務器的dst文件。使用時可根據具體情況選擇使用哪種實現方式。

監控傳輸進度

從前面的介紹中知道,JSch支持在文件傳輸時對傳輸進度的監控。可以實現JSch提供的SftpProgressMonitor接口來完成這個功能。

SftpProgressMonitor接口類的定義為:

 1 SftpProgressMonitor.java  2  3 package com.jcraft.jsch; 4  5 public interface SftpProgressMonitor{ 6   public static final int PUT=0; 7   public static final int GET=1; 8   void init(int op, String src, String dest, long max); 9   boolean count(long count);10   void end();11 }
SftpProgressMonitor

init():當文件開始傳輸時,調用init方法。

count(): 當每次傳輸了一個數據塊后,調用count方法,count方法的參數為這一次傳輸的數據塊大小。

end():當傳輸結束時,調用end方法。

下面是一個簡單的實現:

 1 MyProgressMonitor.java  2  3 package com.longyg.sftp; 4  5 import com.jcraft.jsch.SftpProgressMonitor; 6  7 public class MyProgressMonitor implements SftpProgressMonitor { 8     private long transfered; 9 10     @Override11     public boolean count(long count) {12         transfered = transfered + count;13         System.out.println("Currently transferred total size: " + transfered + " bytes");14         return true;15     }16 17     @Override18     public void end() {19         System.out.println("Transferring done.");20     }21 22     @Override23     public void init(int op, String src, String dest, long max) {24         System.out.println("Transferring begin.");25     }26 }
MyProgressMonitor.java

此時如果改變SFTPTest main方法里調用的put方法,即可實現監控傳輸進度:

 1 SFTPTest.java  2  3 package com.longyg.sftp; 4  5 import java.util.HashMap; 6 import java.util.Map; 7  8 import com.jcraft.jsch.ChannelSftp; 9 10 public class SFTPTest {11 12     public SFTPChannel getSFTPChannel() {13         return new SFTPChannel();14     }15 16     /**17      * @param args18      * @throws Exception19      */20     public static void main(String[] args) throws Exception {21         SFTPTest test = new SFTPTest();22 23         Map<String, String> sftpDetails = new HashMap<String, String>();24         // 設置主機ip,端口,用戶名,密碼25         sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "10.9.167.55");26         sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, "root");27         sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, "arthur");28         sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, "22");29         30         String src = "D://DevSoft//HB-SnagIt1001.rar"; // 本地文件名31         String dst = "/home/omc/ylong/sftp/HB-SnagIt1001.rar"; // 目標文件名32               33         SFTPChannel channel = test.getSFTPChannel();34         ChannelSftp chSftp = channel.getChannel(sftpDetails, 60000);35         36         /**37          * 代碼段138         OutputStream out = chSftp.put(dst, new MyProgressMonitor(), ChannelSftp.OVERWRITE); // 使用OVERWRITE模式39         byte[] buff = new byte[1024 * 256]; // 設定每次傳輸的數據塊大小為256KB40         int read;41         if (out != null) {42             System.out.println("Start to read input stream");43             InputStream is = new FileInputStream(src);44             do {45                 read = is.read(buff, 0, buff.length);46                 if (read > 0) {47                     out.write(buff, 0, read);48                 }49                 out.flush();50             } while (read >= 0);51             System.out.println("input stream read done.");52         }53         **/54         55         chSftp.put(src, dst, new MyProgressMonitor(), ChannelSftp.OVERWRITE); // 代碼段256         57         // chSftp.put(new FileInputStream(src), dst, new MyProgressMonitor(), ChannelSftp.OVERWRITE); // 代碼段358         59         chSftp.quit();60         channel.closeChannel();61     }62 }
SFTPTest.java

 1 logs  2  3 Start to read input stream 4 Currently transferred total size: 262144 bytes 5 Currently transferred total size: 524288 bytes 6 Currently transferred total size: 786432 bytes 7 Currently transferred total size: 1048576 bytes 8 Currently transferred total size: 1310720 bytes 9 Currently transferred total size: 1572864 bytes10 Currently transferred total size: 1835008 bytes11 Currently transferred total size: 2097152 bytes12 Currently transferred total size: 2359296 bytes13 Currently transferred total size: 2621440 bytes14 Currently transferred total size: 2883584 bytes15 Currently transferred total size: 3145728 bytes16 Currently transferred total size: 3407872 bytes17 Currently transferred total size: 3670016 bytes18 Currently transferred total size: 3848374 bytes19 input stream read done.
logs

當然這個SftpProgressMonitor的實現實在太簡單。JSch每次傳輸一個數據塊,就會調用count方法來實現主動進度通知。

現在我們希望每間隔一定的時間才獲取一下文件傳輸的進度。。。看看下面的SftpProgressMonitor實現:

  1 FileProgressMonitor.java   2   3 package com.longyg.sftp;  4   5 import java.text.DecimalFormat;  6 import java.util.Timer;  7 import java.util.TimerTask;  8   9 import com.jcraft.jsch.SftpProgressMonitor; 10  11 public class FileProgressMonitor extends TimerTask implements SftpProgressMonitor { 12      13     private long progressInterval = 5 * 1000; // 默認間隔時間為5秒 14      15     private boolean isEnd = false; // 記錄傳輸是否結束 16      17     private long transfered; // 記錄已傳輸的數據總大小 18      19     private long fileSize; // 記錄文件總大小 20      21     private Timer timer; // 定時器對象 22      23     private boolean isScheduled = false; // 記錄是否已啟動timer記時器 24      25     public FileProgressMonitor(long fileSize) { 26         this.fileSize = fileSize; 27     } 28      29     @Override 30     public void run() { 31         if (!isEnd()) { // 判斷傳輸是否已結束 32             System.out.println("Transfering is in progress."); 33             long transfered = getTransfered(); 34             if (transfered != fileSize) { // 判斷當前已傳輸數據大小是否等于文件總大小 35                 System.out.println("Current transfered: " + transfered + " bytes"); 36                 sendProgressMessage(transfered); 37             } else { 38                 System.out.println("File transfering is done."); 39                 setEnd(true); // 如果當前已傳輸數據大小等于文件總大小,說明已完成,設置end 40             } 41         } else { 42             System.out.println("Transfering done. Cancel timer."); 43             stop(); // 如果傳輸結束,停止timer記時器 44             return; 45         } 46     } 47      48     public void stop() { 49         System.out.println("Try to stop progress monitor."); 50         if (timer != null) { 51             timer.cancel(); 52             timer.purge(); 53             timer = null; 54             isScheduled = false; 55         } 56         System.out.println("Progress monitor stoped."); 57     } 58      59     public void start() { 60         System.out.println("Try to start progress monitor."); 61         if (timer == null) { 62             timer = new Timer(); 63         } 64         timer.schedule(this, 1000, progressInterval); 65         isScheduled = true; 66         System.out.println("Progress monitor started."); 67     } 68      69     /** 70      * 打印progress信息 71      * @param transfered 72      */ 73     private void sendProgressMessage(long transfered) { 74         if (fileSize != 0) { 75             double d = ((double)transfered * 100)/(double)fileSize; 76             DecimalFormat df = new DecimalFormat( "#.##");  77             System.out.println("Sending progress message: " + df.format(d) + "%"); 78         } else { 79             System.out.println("Sending progress message: " + transfered); 80         } 81     } 82  83     /** 84      * 實現了SftpProgressMonitor接口的count方法 85      */ 86     public boolean count(long count) { 87         if (isEnd()) return false; 88         if (!isScheduled) { 89             start(); 90         } 91         add(count); 92         return true; 93     } 94  95     /** 96      * 實現了SftpProgressMonitor接口的end方法 97      */ 98     public void end() { 99         setEnd(true);100         System.out.println("transfering end.");101     }102     103     private synchronized void add(long count) {104         transfered = transfered + count;105     }106     107     private synchronized long getTransfered() {108         return transfered;109     }110     111     public synchronized void setTransfered(long transfered) {112         this.transfered = transfered;113     }114     115     private synchronized void setEnd(boolean isEnd) {116         this.isEnd = isEnd;117     }118     119     private synchronized boolean isEnd() {120         return isEnd;121     }122 123     public void init(int op, String src, String dest, long max) {124         // Not used for putting InputStream125     }126 }
FileProgressMonitor

再次修改SFTPTest main方法里的put方法,改為使用新的SftpProgressMonitor的實現類對象monitor作為參數,注意新的monitor對象的構造函數需要傳入文件大小作為參數:

 1 SFTPTest.java  2  3 package com.longyg.sftp; 4  5 import java.io.File; 6 import java.util.HashMap; 7 import java.util.Map; 8  9 import com.jcraft.jsch.ChannelSftp;10 11 public class SFTPTest {12 13     public SFTPChannel getSFTPChannel() {14         return new SFTPChannel();15     }16 17     /**18      * @param args19      * @throws Exception20      */21     public static void main(String[] args) throws Exception {22         SFTPTest test = new SFTPTest();23 24         Map<String, String> sftpDetails = new HashMap<String, String>();25         // 設置主機ip,端口,用戶名,密碼26         sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, "10.9.167.55");27         sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, "root");28         sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, "arthur");29         sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, "22");30         31         String src = "D://DevSoft//HB-SnagIt1001.rar"; // 本地文件名32         String dst = "/home/omc/ylong/sftp/HB-SnagIt1001.rar"; // 目標文件名33               34         SFTPChannel channel = test.getSFTPChannel();35         ChannelSftp chSftp = channel.getChannel(sftpDetails, 60000);36         37         File file = new File(src);38         long fileSize = file.length();39         40         /**41          * 代碼段142         OutputStream out = chSftp.put(dst, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); // 使用OVERWRITE模式43         byte[] buff = new byte[1024 * 256]; // 設定每次傳輸的數據塊大小為256KB44         int read;45         if (out != null) {46             System.out.println("Start to read input stream");47             InputStream is = new FileInputStream(src);48             do {49                 read = is.read(buff, 0, buff.length);50                 if (read > 0) {51                     out.write(buff, 0, read);52                 }53                 out.flush();54             } while (read >= 0);55             System.out.println("input stream read done.");56         }57         **/58         59         chSftp.put(src, dst, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); // 代碼段260         61         // chSftp.put(new FileInputStream(src), dst, new FileProgressMonitor(fileSize), ChannelSftp.OVERWRITE); // 代碼段362         63         chSftp.quit();64         channel.closeChannel();65     }66 }
SFTPTest

再次運行,結果輸出為:

 1 logs  2  3 Try to start progress monitor. 4 Progress monitor started. 5 Transfering is in progress. 6 Current transfered: 98019 bytes 7 Sending progress message: 2.55% 8 Transfering is in progress. 9 Current transfered: 751479 bytes10 Sending progress message: 19.53%11 Transfering is in progress.12 Current transfered: 1078209 bytes13 Sending progress message: 28.02%14 ......15 Transfering is in progress.16 Current transfered: 3430665 bytes17 Sending progress message: 89.15%18 transfering end.19 Transfering done. Cancel timer.20 Try to stop progress monitor.21 Progress monitor stoped.
logs

現在,程序每隔5秒鐘才會打印一下進度信息。可以修改FileProgressMonitor類里的progressInterval變量的值,來修改默認的間隔時間。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宣武区| 石林| 长垣县| 土默特左旗| 车险| 水富县| 九龙城区| 宁强县| 永安市| 沧州市| 阿坝县| 佳木斯市| 互助| 中卫市| 融水| 白城市| 萍乡市| 清流县| 海原县| 洛扎县| 汝阳县| 卓资县| 宜宾市| 宁都县| 延长县| 南阳市| 澄江县| 齐齐哈尔市| 鄂托克前旗| 凌海市| 阳西县| 璧山县| 彰化县| 万荣县| 江山市| 和顺县| 东乡族自治县| 芜湖市| 洛隆县| 涿鹿县| 广饶县|