java jsch實現sftp檔案上傳,並且控制上傳的速度,同時監控上傳進度
阿新 • • 發佈:2018-11-27
工作中,有些環境頻寬有限,比如說專線,通常頻寬比較小,又不便宜,當業務量大的時間,如果在專線上還要傳輸檔案的話,往往在檔案傳輸的時間會導致頻寬佔慢,就有可能導致時實交易進不來,有可能影響交易,今天貼一下 jsch實現sftp檔案上傳,並且控制上傳的速度,同時監控上傳進度,供大家參考。
maven 工程下先把jsch 依賴新增到pom.xml
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency>
java 程式碼如下:
FileUploadMain.java
package com.sftp; import com.jcraft.jsch.*; import java.io.*; import java.util.Properties; /** * 使用 JSch 上傳檔案,並且控制上傳的速度,同時監控上傳進度 */ public class FileUploadMain { public static void main(String[] args) { JSch jsch = new JSch(); UploadMonitor monitor = null; try { Session session = jsch.getSession("ftpuser", "118.24.157.71", 22); session.setPassword("Pass!112%"); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); Channel channel = session.openChannel("sftp"); channel.connect(); ChannelSftp c = (ChannelSftp) channel; String pwd = c.pwd(); System.out.println(pwd); String src = "D:\\software\\apache-tomcat-6.0.36.zip"; String dst = c.pwd() + "/apache-tomcat-6.0.36.zip"; monitor = new UploadMonitor(new File(src).length()); //是否限制上傳速度 boolean speedLimit = false; if (speedLimit) { OutputStream os = c.put(dst, monitor, ChannelSftp.OVERWRITE); byte[] buff = new byte[1024 * 10]; // 設定每次傳輸的資料塊大小為256KB int read; if (os != null) { FileInputStream fis = new FileInputStream(src); do { read = fis.read(buff, 0, buff.length); if (read > 0) { os.write(buff, 0, read); } os.flush(); } while (read >= 0); } } else { c.put(src, dst, monitor, ChannelSftp.OVERWRITE); } c.disconnect(); session.disconnect(); } catch (Exception e) { /** * 發生異常後,終止監聽 */ monitor.stop(); } } }
UploadMonitor.java
package com.sftp;
import com.jcraft.jsch.SftpProgressMonitor;
import java.text.NumberFormat;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author kevin.chen
*/
public class UploadMonitor implements SftpProgressMonitor, Runnable {
/**
* 檔案的總大小
*/
private long maxCount = 0;
private long uploaded = 0;
long startTime = 0L;
private boolean isScheduled = false;
ScheduledExecutorService executorService;
public UploadMonitor(long maxCount) {
this.maxCount = maxCount;
}
/**
* 當檔案開始傳輸時,呼叫init方法
*
* @param op
* @param src
* @param dest
* @param max
*/
@Override
public void init(int op, String src, String dest, long max) {
System.out.println("開始上傳檔案:" + src + "至遠端:" + dest + "檔案總大小:" + maxCount / 1024 + "KB");
startTime = System.currentTimeMillis();
}
/**
* 當每次傳輸了一個數據塊後,呼叫count方法,count方法的引數為這一次傳輸的資料塊大小
*
* @param count
* @return
*/
@Override
public boolean count(long count) {
if (!isScheduled) {
createTread();
}
uploaded += count;
System.out.println("本次上傳大小:" + count / 1024 + "KB,");
if (count > 0) {
return true;
}
return false;
}
/**
* 當傳輸結束時,呼叫end方法
*/
@Override
public void end() {
}
/**
* 建立一個執行緒每隔一定時間,輸出一下上傳進度
*/
public void createTread() {
executorService = Executors.newSingleThreadScheduledExecutor();
//1秒鐘後開始執行,每2杪鍾執行一次
executorService.scheduleWithFixedDelay(this, 1, 2, TimeUnit.SECONDS);
isScheduled = true;
}
@Override
public void run() {
NumberFormat format = NumberFormat.getPercentInstance();
format.setMaximumFractionDigits(2);
format.setMinimumFractionDigits(2);
String value = format.format((uploaded / (double) maxCount));
System.out.println("已傳輸:" + uploaded / 1024 + "KB,傳輸進度:" + value);
if (uploaded == maxCount) {
stop();
long endTime = System.currentTimeMillis();
System.out.println("傳輸完成!用時:" + (endTime - startTime) / 1000 + "s");
}
}
public void stop() {
boolean isShutdown = executorService.isShutdown();
if (!isShutdown) {
executorService.shutdown();
}
}
}
在UploadMonitor類中,方法 public boolean count(long count) 因為每傳送一次資料都會執行一次,比較頻繁,所以我們單獨建立一個執行緒定時查詢一下上傳進度
歡迎,收藏轉載! 生產使用中需要再微調,比如日誌列印