1. 程式人生 > >java jsch實現sftp檔案上傳,並且控制上傳的速度,同時監控上傳進度

java jsch實現sftp檔案上傳,並且控制上傳的速度,同時監控上傳進度

工作中,有些環境頻寬有限,比如說專線,通常頻寬比較小,又不便宜,當業務量大的時間,如果在專線上還要傳輸檔案的話,往往在檔案傳輸的時間會導致頻寬佔慢,就有可能導致時實交易進不來,有可能影響交易,今天貼一下 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) 因為每傳送一次資料都會執行一次,比較頻繁,所以我們單獨建立一個執行緒定時查詢一下上傳進度

歡迎,收藏轉載! 生產使用中需要再微調,比如日誌列印