天天看點

JSch實作sftp上傳檔案

一.JSch依賴坐标

<dependency>
  <groupId>com.jcraft</groupId>
  <artifactId>jsch</artifactId>
  <version>0.1.53</version>
</dependency>
           

二.上傳檔案代碼

package sftpTest;

import java.io.File;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

public class JSchUtil {
    private static final String IP = "192.168.88.206";
    private static final int port = ;
    private static final String username = "root";
    private static final String password = "123456";

    private static JSch jsch = new JSch();

    /**
     * 擷取連接配接
     * @return
     * @throws JSchException
     */
    public static SFTP getConnect() throws JSchException {
        Session session = jsch.getSession(username, IP, port);
        session.setPassword(password);
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();
        ChannelSftp channel = (ChannelSftp)session.openChannel("sftp");
        SFTP sftp = new SFTP();
        sftp.setSession(session);
        sftp.setChannel(channel);
        return sftp;
    }

    /**
     * 上傳檔案到遠端伺服器(此方法上傳檔案後,檔案名不變)
     * @param sftp sftp對象
     * @param src 本地源檔案路徑
     * @param remotePath 遠端伺服器路徑(檔案夾,不包含檔案名)
     * @throws JSchException
     * @throws SftpException
     */
    public static void uploadFile(SFTP sftp, String src, String remotePath) throws JSchException, SftpException {
        ChannelSftp channel = sftp.getChannel();
        channel.connect();
        try {
            try {
                channel.cd(remotePath);
            } catch (Exception e) {
                mkdir(remotePath, channel);
            }
            File file = new File(src);
            // 擷取檔案絕對路徑
            src = file.getAbsolutePath();
            // 使用put方法,兩個參數路徑都是絕對的
            channel.put(src, channel.pwd());
        } catch (Exception e) {
            //沒弄日志,暫時列印....
            System.out.println("上傳失敗! 原因: " + e.getMessage());
        } finally {
            disConn(sftp.getSession(), channel);
        }

    }

    /**
     * 建立多級目錄并cd到該目錄下
     * @param remotePath
     * @param channel
     * @throws SftpException
     */
    public static void mkdir(String remotePath, ChannelSftp channel) throws SftpException {
        String[] folders = remotePath.split("/");
        if (remotePath.startsWith("/")) {
            channel.cd("/");
        }
        for (String folder : folders) {
            if (folder.length() > ) {
                try {
                    channel.cd(folder);
                } catch (SftpException e) {
                    channel.mkdir(folder);
                    channel.cd(folder);
                }
            }
        }

    }

    /**
     * 關閉連接配接
     * @param session
     * @param channel
     */
    public static void disConn(Session session, ChannelSftp channel) {
        if (channel != null) {
            channel.disconnect();
            channel.exit();
            channel = null;
        }
        if (session != null) {
            session.disconnect();
            session = null;
        }
    }

    public static void main(String[] args) throws SftpException, JSchException {
        SFTP sftp = getConnect();
        String src = "D:\\test.txt";
        String remotePath = "/root/data/test/";
        uploadFile(sftp, src, remotePath);
    }
}

class SFTP {
    private Session session;
    private ChannelSftp channel;

    public Session getSession() {
        return session;
    }
    public void setSession(Session session) {
        this.session = session;
    }
    public ChannelSftp getChannel() {
        return channel;
    }
    public void setChannel(ChannelSftp channel) {
        this.channel = channel;
    }

}
           

三.需要注意的問題

  1. JSch

    自帶的

    api

    不能直接在遠端伺服器上建立多級目錄,需要自己寫個
  2. 建立多級目錄的方法中,已經

    cd

    到目标檔案夾下了,是以上傳的方法中不要再使用

    cd()

    方法,否則會報錯
  3. 本地檔案要擷取到絕對路徑才能夠使用

    put()

    方法,否則會報錯:找不到源檔案路徑
  4. 目标路徑要用

    pwd()

    方法擷取絕對路徑,再使用

    put()

    方法