天天看点

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) 因为每发送一次数据都会执行一次,比较频繁,所以我们单独创建一个线程定时查询一下上传进度

欢迎,收藏转载! 生产使用中需要再微调,比如日志打印