SFTP和Channel

SFTP是Secure File Transfer Protocol的縮寫,安全文件傳送協(xié)議??梢詾閭鬏斘募峁┮环N安全的加密方法。SFTP為SSH的一部份,是一種傳輸文件到服務(wù)器的安全方式。SFTP是使用加密傳輸認(rèn)證信息和傳輸?shù)臄?shù)據(jù),所以,使用SFTP是非常安全的。但是,由于這種傳輸方式使用了加密/解密技術(shù),所以傳輸效率比普通的FTP要低得多,如果您對(duì)網(wǎng)絡(luò)安全性要求更高時(shí),可以使用SFTP代替FTP。

1.實(shí)現(xiàn)依賴Jsch-0.1.54.jar

可以在mvn repository 依賴到項(xiàng)目來(lái),我使用的依賴如下:

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.54</version>
</dependency>

2.引入Jar包之后,我們就先可配置化我們SFTP的一些參數(shù)

新建 config.properties

work order photo SFTP config.

sftp.ip=10.32.233.111
sftp.port=22
sftp.userName=root
sftp.password=kaifa123
sftp.timeout=60000
sftp.src=D:\ftpLocalFile
sftp.dst= /opt/soft/sftp/
sftp.retryTime=3
@see ConfigEntity#getSftpXXX() 方法將從config.properties文件讀取相應(yīng)配置信息

3.封裝創(chuàng)建獲得SFTP服務(wù)器的連接的方法及釋放連接的方法

解釋一下SFTP的整個(gè)調(diào)用過程,這個(gè)過程就是通過Ip、Port、Username、Password獲取一個(gè)Session,然后通過Session打開SFTP通道(獲得SFTP Channel對(duì)象),再在建立通道(Channel)連接,最后我們就是通過這個(gè)Channel對(duì)象來(lái)調(diào)用SFTP的各種操作方法.總是要記得,我們操作完SFTP需要手動(dòng)斷開Channel連接與Session連接。

直接貼相應(yīng)的方法代碼:
    /**
     * 獲得SFTP Channel
     * @return ChannelSftp Instance
     * @throws JSchException
     */
    public ChannelSftp getChannel() throws JSchException {
        String ftpHost = config.getSftpIp();
        int ftpPort = config.getSftpPort();
        String ftpUserName = config.getSftpUserName();
        String ftpPassword = config.getSftpPassword();
        // 創(chuàng)建JSch對(duì)象
        JSch jsch = new JSch();
        // 根據(jù)用戶名,主機(jī)ip,端口獲取一個(gè)Session對(duì)象
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort);
        //logger.info("Session created.");
        if (ftpPassword != null) {
            // 設(shè)置密碼
            session.setPassword(ftpPassword);
        }
        Properties configTemp = new Properties();
        configTemp.put("StrictHostKeyChecking", "no");
        // 為Session對(duì)象設(shè)置properties
        session.setConfig(configTemp);
        // 設(shè)置timeout時(shí)間
        session.setTimeout(config.getSftpTimeout());
        session.connect();
        // 通過Session建立鏈接
        // 打開SFTP通道
        channel = session.openChannel("sftp");
        // 建立SFTP通道的連接
        channel.connect();
        logger.info("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName + ", returning: " + channel);
        return (ChannelSftp) channel;
    }

    /**
     * 斷開SFTP Channel、Session連接
     * @throws Exception
     */
    public void closeChannel() throws Exception {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
        logger.info("disconnected SFTP successfully!");
    }

    @Autowired
    private ConfigEntity config; //Ignore this

4.調(diào)用代碼示例

ChannelSftp chSftp = getChannel();
// 本地文件名
String src = config.getSftpLocalPath() + orderPhoto.getNewPhotoName();
// 目標(biāo)文件名
String dst = config.getSftpDstPath() + orderPhoto.getNewPhotoName();
chSftp.put(src, dst, ChannelSftp.OVERWRITE);
chSftp.quit();
closeChannel();

Jsch-0.1.54.jar 學(xué)習(xí)了解

ChannelSftp類是JSch實(shí)現(xiàn)SFTP核心類,它包含了所有SFTP的方法,如:
文件上傳put(),文件下載get(),進(jìn)入指定目錄cd().
得到指定目錄下的文件列表ls().
重命名指定文件或目錄rename().
刪除指定文件rm(),創(chuàng)建目錄mkdir(),刪除目錄rmdir().
大家引用方法時(shí)可以快速參考一下,具體傳參需參考源碼~

最后還要提一下的就是JSch支持的三種文件傳輸模式:

  • APPEND 追加模式,如果目標(biāo)文件已存在,傳輸?shù)奈募⒃谀繕?biāo)文件后追加。
  • RESUME 恢復(fù)模式,如果文件已經(jīng)傳輸一部分,這時(shí)由于網(wǎng)絡(luò)或其他任何原因?qū)е挛募鬏斨袛啵绻乱淮蝹鬏斚嗤奈募?,則會(huì)從上一次中斷的地方續(xù)傳。
  • OVERWRITE 完全覆蓋模式,這是JSch的默認(rèn)文件傳輸模式,即如果目標(biāo)文件已經(jīng)存在,傳輸?shù)奈募⑼耆采w目標(biāo)文件,產(chǎn)生新的文件。

——–End Learning———-

二、Java實(shí)現(xiàn)FTP文件上傳(一般是Windows使用)

直接上代碼
/**
 * 連接到服務(wù)器
 * @return true 連接服務(wù)器成功,false 連接服務(wù)器失敗
 */
    public boolean connectServer() {
        boolean flag = true;
        if (ftpClient == null) {
            int reply;
            try {
                if(true){
                    ftpClient = new FTPClient();
                    ftpClient.connect(config.getFtpIp(),config.getFtpPort());
                    ftpClient.login(config.getFtpUserName(), config.getFtpPassword());
                    reply = ftpClient.getReplyCode();
                    ftpClient.setDataTimeout(60000);
                    if (!FTPReply.isPositiveCompletion(reply)) {
                        ftpClient.disconnect();
                        logger.info("FTP server refuse connect!");
                        flag = false;
                    }
                }else{
                    flag = false;
                }
            } catch (SocketException e) {
                flag = false;
                e.printStackTrace();
                logger.info("Login ftp server " + config.getFtpIp() + " failed,connect timeout!");
                logger.error("Login ftp server " + config.getFtpIp() + " failed",e);
            } catch (IOException e) {
                flag = false;
                e.printStackTrace();
                logger.info("Login ftp server  " + config.getFtpIp() + " failed,F(xiàn)TP server couldn't open!");
                logger.error("Login ftp server " + config.getFtpIp() + " failed",e);
            }
        }
        return flag;
    }

    public boolean disConnectServer() {
        boolean flag = true;
        if (ftpClient != null) {
            try{
                ftpClient.logout();
                ftpClient.disconnect();
            }catch (Exception e){
                flag = false;
                logger.info("Disconnect ftp server  " + config.getFtpIp() + " failed!");
                logger.error("Disconnect ftp server  " + config.getFtpIp() + " failed",e);
            }
        }
        return flag;
    }

    /**
     * @param remoteFile
     * @param localFile
     * @return
     * @throws IOException
     */
    public boolean uploadFile(String remoteFile, File localFile)
            throws IOException {
        boolean flag = false;
     /*   File file = new File("D://"+UUID.randomUUID()+".jpg");
        if (!file.exists()) {
            file.createNewFile();
        }*/
        InputStream in = new FileInputStream(localFile);
        // IOUtils.copy(in,new FileOutputStream(file));
        //String remote = new String(remoteFile.getBytes("GBK"),"iso-8859-1");
        /*ftpClient.setBufferSize(1024*1024);
        ftpClient.setControlEncoding("utf-8");
        ftpClient.enterLocalPassiveMode();*/
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        ftpClient.changeWorkingDirectory("/picture/pp");
        if (ftpClient.storeFile(remoteFile, in)) {
            flag = true;
            logger.info(localFile.getAbsolutePath() + "upload successfully!");
        } else {
            logger.info(localFile.getAbsolutePath() + "upload failed!");
        }
        in.close();
        return flag;
    }

    /**
     * 上傳單個(gè)文件,并重命名
     * @param local  --本地文件路徑
     * @param remote --本地文件父文件夾路徑
     * @return true 上傳成功,false 上傳失敗
     * @throws IOException
     */
    public boolean uploadFile(String local, String remote) throws IOException {
        boolean flag = true;
        String remoteFileName = remote;
        File f = new File(local);
        if (!uploadFile(remoteFileName, f)) {
            flag = false;
        }
        return flag;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容