SFTP下载文件并显示进度

时间:2021-06-13 09:57:24

在解决从远程服务器上下载文件是时候,我遇到了好多方法,也许不能解决我的问题,但也是一个知识点嘛!如jsch直接读取文件再保存,SCPClient和本篇要介绍的SFTP等方法均可实现。

SFTPSecure File Transfer Protocol的缩写,安全文件传送协议。可以为传输文件提供一种安全的加密方法。sftpftp 有着几乎一样的语法和功能。SFTPSSH的一部分,是一种传输档案至 Blogger 伺服器的安全方式。其实在SSH软件包中,已经包含了一个叫作SFTP(Secure File Transfer Protocol)的安全文件传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接操作,所以从某种意义上来说,SFTP并不像一个服务器程序,而更像是一个客户端程序。SFTP同样是使用加密传输认证信息和传输的数据,所以,使用SFTP是非常安全的。但是,由于这种传输方式使用了加密/解密技术,所以传输效率比普通的FTP要低得多,如果您对网络安全性要求更高时,可以使用SFTP代替FTP

而我们可以使用SFTP从远程机器上下载文件,示例代码如下:

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.HashMap;

import java.util.Map;

 

import com.jcraft.jsch.Channel;

import com.jcraft.jsch.ChannelSftp;

import com.jcraft.jsch.JSch;

import com.jcraft.jsch.JSchException;

import com.jcraft.jsch.Session;

import com.jcraft.jsch.SftpATTRS;

 

import qataskclient.MyProgressMonitor;

 

public class DownFile {

  

private static JSch jsch;

private static Session session;

static String userName = "********";

static String password = "********";

//创建连接

public static void connect(String host) throws JSchException {

     jsch = new JSch();

     session = jsch.getSession(userName, host, 22);

     session.setPassword(password);

     java.util.Properties config = new java.util.Properties();

     config.put("StrictHostKeyChecking", "no");

     session.setConfig(config);

     session.connect();

}

 

    public static void main(String[] args) throws Exception {

     Channel channel = null;

     connect("XXX.XXX.XXX.XXX");

        Map sftpDetails = new HashMap();

        // 设置主机ip,端口,用户名,密码

        channel = session.openChannel("sftp"); // 打开SFTP通道

        channel.connect(); // 建立SFTP通道的连接

        ChannelSftp chSftp =(ChannelSftp) channel;

       

        String filename = "/opt/web/usdt_infolist_sale/logs/catalina.out";//需要下载的文件

        SftpATTRS attr = chSftp.stat(filename);

        long fileSize = attr.getSize();

       

        String dst = "E:\\KuGou\\catalina.out";//存储到本地的文件

        OutputStream out = new FileOutputStream(dst);

        try {

           

            chSftp.get(filename, dst); //下载文件

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            chSftp.quit();

        session.disconnect();

        }

    }

}

通过上面的方法,我们就可以从远程服务器上以安全的方式下载文件。当然有的时候,我们下载文件时希望看到下载进度,此时需要另外加一个回调函数来显示进度。回调函数,显示进度的代码如下:

import com.jcraft.jsch.SftpProgressMonitor;

public class MyProgressMonitor implements SftpProgressMonitor {

private long transfered;

@Override

    public boolean count(long count) {

        transfered = transfered + count;

        if(transfered<1024)

        {

               System.out.println("Currently transferred total size: " + transfered + " bytes");

        }

        if ((transfered> 1024) && (transfered<1048576))

        {

               System.out.println("Currently transferred total size: " + (transfered/1024) + "K bytes");

        }

        else

        {

               System.out.println("Currently transferred total size: " +( transfered/1024/1024) + "M bytes");

        }

        return true;

    }

 

    @Override

    public void end() {

        System.out.println("Transferring done.");

    }

 

    @Override

    public void init(int op, String src, String dest, long max) {

        System.out.println("Transferring begin.");

    }

}

使用SftpProgressMonitor来监控下载的进度,当然我也要修改一下下载文件的部分,具体代码如下:

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.HashMap;

import java.util.Map;

 

import com.jcraft.jsch.Channel;

import com.jcraft.jsch.ChannelSftp;

import com.jcraft.jsch.JSch;

import com.jcraft.jsch.JSchException;

import com.jcraft.jsch.Session;

import com.jcraft.jsch.SftpATTRS;

 

import qataskclient.MyProgressMonitor;

 

public class DownFile {

  

    private static JSch jsch;

    private static Session session;

    static String userName = "********";

    static String password = "********";

    //连接到远程服务器

    public static void connect(String host) throws JSchException {

        jsch = new JSch();

        session = jsch.getSession(userName, host, 22);

        session.setPassword(password);

        java.util.Properties config = new java.util.Properties();

        config.put("StrictHostKeyChecking", "no");

        session.setConfig(config);

        session.connect();

    }

   

    public static void main(String[] args) throws Exception {

         Channel channel = null;

         connect("XXX.XXX.XXX.XXX");

        Map sftpDetails = new HashMap();

        // 设置主机ip,端口,用户名,密码

        channel = session.openChannel("sftp"); // 打开SFTP通道

        channel.connect(); // 建立SFTP通道的连接

        ChannelSftp chSftp =(ChannelSftp) channel;

       

        String filename = "/opt/web/usdt_infolist_sale/logs/catalina.out";

        SftpATTRS attr = chSftp.stat(filename);

        long fileSize = attr.getSize();

       

        String dst = "E:\\KuGou\\catalina.out";

        OutputStream out = new FileOutputStream(dst);

        try {

            //添加回调函数监控进度

            InputStream is = chSftp.get(filename,  new MyProgressMonitor());

            byte[] buff = new byte[1024 * 2];

            int read;

            if (is != null) {

                System.out.println("Start to read input stream");

                do {

                    read = is.read(buff, 0, buff.length);

                    if (read > 0) {

                        out.write(buff, 0, read);

                    }

                    out.flush();

                } while (read >= 0);

                System.out.println("input stream read done.");

            }

       

        } catch (Exception e) {

            e.printStackTrace();

        } finally {

            chSftp.quit();

            session.disconnect();

        }

    }

}

 当我们再次才能这段代码时,就能实时显示出下载进度,并且能根据下载量的大小,转化成以KM为单位的显示。