1. 程式人生 > >JSCH SFTP 檔案下載

JSCH SFTP 檔案下載


JSCH SFTP


  • 簡單優雅 , 靈活的配置
  • 複製即可執行
  • 能解決org.apache.commons.net.ftp.FTPClient通過協議SSH2進行SFTP連線時,遠端不支援SSH2這種方式的連線的錯誤
  • Could not parse response code.Server Reply: SSH-2.0-OpenSSH_5.3

POM


        <!--JSCH FTP-->
        <dependency>
            <groupId>com.jcraft</groupId
>
<artifactId>jsch</artifactId> <version>0.1.49</version> </dependency>

配置: importDB.properties


# SFTP 資訊
#.遠端資料檔案下載
# 1.Ip
# 2.Port
# 3.UserName
# 4.PassWord
# 5.目標檔案
# 6.本地檔案
SFTP_HOST=xxx.xx.xx.xxx
SFTP_PORT=22
SFTP_USERNAME=xxxx
SFTP_PASSWORD=xxxx
SFTP_REMOTE_PATH=/root/zip.zip
SFTP_LOCAL_PATH=D:\\zip.zip

功能實現


import java.io.InputStream;
import java.util.Properties;
import com.jcraft.jsch.*;

public class SFTPGetTest {

    /* SFTP 連線資訊 */
    private static String SFTP_HOST;
    private static Integer SFTP_PORT;
    private static String SFTP_USERNAME;
    private static String SFTP_PASSWORD;
    /* 目標檔案與下載地址 */
private static String SFTP_REMOTE_PATH; private static String SFTP_LOCAL_PATH; /* 初始化:載入配置 */ public static void init() { Properties properties=new Properties(); InputStream resourceAsStream = Object.class.getResourceAsStream("/importDB.properties"); if(resourceAsStream!=null){ try { properties.load(resourceAsStream); SFTP_HOST=properties.getProperty("SFTP_HOST"); SFTP_PORT=Integer.parseInt(properties.getProperty("SFTP_PORT")); SFTP_USERNAME=properties.getProperty("SFTP_USERNAME"); SFTP_PASSWORD=properties.getProperty("SFTP_PASSWORD"); SFTP_REMOTE_PATH=properties.getProperty("SFTP_REMOTE_PATH"); SFTP_LOCAL_PATH=properties.getProperty("SFTP_LOCAL_PATH"); } catch (Exception e) { e.printStackTrace(); } } } /*初始值校驗*/ private static boolean valid(){ if(SFTP_HOST==null || SFTP_HOST.trim().length()==0) return false; if(SFTP_PORT==null || SFTP_PORT==0) return false; if(SFTP_USERNAME==null || SFTP_USERNAME.trim().length()==0) return false; if(SFTP_PASSWORD==null || SFTP_PASSWORD.trim().length()==0) return false; if(SFTP_REMOTE_PATH==null || SFTP_REMOTE_PATH.trim().length()==0) return false; if(SFTP_LOCAL_PATH==null || SFTP_LOCAL_PATH.trim().length()==0) return false; return true; } /* 獲取連線渠道 */ private static Session session=null; private static Channel channel=null; public static ChannelSftp getChannel() throws JSchException { /*建立JSch物件*/ JSch jsch = new JSch(); /*根據使用者名稱,主機ip,埠獲取一個Session物件*/ session = jsch.getSession(SFTP_USERNAME, SFTP_HOST, SFTP_PORT); /*設定密碼*/ session.setPassword(SFTP_PASSWORD); /*Session 配置*/ Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.setTimeout(60000); /* Session 連結建立 */ session.connect(); System.out.println("SESSION IS CONNECTED !"); /* 開啟SFTP通道*/ channel = session.openChannel("sftp"); channel.connect(); System.out.println(" SFTP IS CONNECTED !"); return (ChannelSftp) channel; } /* 渠道/Session 關閉 */ public static void closeChannel() throws Exception { if (channel != null) { channel.disconnect(); } if (session != null) { session.disconnect(); } } public static void main(String[] args) throws Exception { /*初始化*/ init(); /*校驗*/ if(valid()){ /*連線資訊*/ ChannelSftp chSftp = getChannel(); /*傳入目標檔案*/ SftpATTRS attr = chSftp.stat(SFTP_REMOTE_PATH); /*檔案大小*/ long fileSize = attr.getSize(); try { /*下載*/ /*引數: 目標檔案,本地檔案, ? */ chSftp.get(SFTP_REMOTE_PATH, SFTP_LOCAL_PATH, new FileProgressMonitor(fileSize)); } catch (Exception e) { e.printStackTrace(); } finally { /*關閉*/ chSftp.quit(); closeChannel(); } } } }

進度監控


import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;

import com.jcraft.jsch.SftpProgressMonitor;

public class FileProgressMonitor extends TimerTask implements SftpProgressMonitor {
    private long progressInterval = 5 * 1000; // 預設間隔時間為5秒
    private boolean isEnd = false; // 記錄傳輸是否結束
    private long transfered; // 記錄已傳輸的資料總大小
    private long fileSize; // 記錄檔案總大小
    private Timer timer; // 定時器物件
    private boolean isScheduled = false; // 記錄是否已啟動timer記時器
    public FileProgressMonitor(long fileSize) {
        this.fileSize = fileSize;
    }

    @Override
    public void run() {
        if (!isEnd()) { // 判斷傳輸是否已結束
            long transfered = getTransfered();
            if (transfered != fileSize) { // 判斷當前已傳輸資料大小是否等於檔案總大小
                System.out.println(" 傳輸 " + transfered + " bytes");
                /*輸出日誌資訊*/
                if (fileSize != 0) {
                    double d = ((double)transfered * 100)/(double)fileSize;
                    DecimalFormat df = new DecimalFormat( "#.##");
                    System.out.println(" 進度 " + df.format(d) + "%");
                } else {
                    System.out.println("已完成");
                }
            } else {
                setEnd(true); // 如果當前已傳輸資料大小等於檔案總大小,說明已完成,設定end
            }
        } else {
            if (timer != null) {
                timer.cancel();
                timer.purge();
                timer = null;
                isScheduled = false;
            }
            return;
        }
    }

    public void start() {
        if (timer == null) {
            timer = new Timer();
        }
        timer.schedule(this, 1000, progressInterval);
        isScheduled = true;
    }
    /** 實現了SftpProgressMonitor介面的count方法  */
    public boolean count(long count) {
        if (isEnd()) return false;
        if (!isScheduled) {
            start();
        }
        add(count);
        return true;
    }
    /**  實現了SftpProgressMonitor介面的end方法 */
    public void end() {
        setEnd(true);
    }

    private synchronized void add(long count) {
        transfered = transfered + count;
    }

    private synchronized long getTransfered() {
        return transfered;
    }

    public synchronized void setTransfered(long transfered) {
        this.transfered = transfered;
    }

    private synchronized void setEnd(boolean isEnd) {
        this.isEnd = isEnd;
    }

    private synchronized boolean isEnd() {
        return isEnd;
    }

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