sftp上传下载

package com.sjtd.utils;

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 com.jcraft.jsch.SftpException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import java.util.Vector;

/**
 * @Description: SFTP客户端
 * @author lss
 * @date 2020年8月17日 下午 20:17:11
 */
public class SftpClient {

    private final static Logger logger = LoggerFactory.getLogger(SftpClient.class);

    private static String host = "127.0.0.1";

    private static String username = "lss";

    private static String password = "1234";

    /** 密钥文件路径*/
    protected static String privateKey;

    /** 密钥口令 */
    protected static String passphrase;

    private static int port = 22;

    private static ChannelSftp sftp = null;

    private static Session sshSession = null;

    public SftpClient(String host, String username, String password) {
        SftpClient.host = host;
        SftpClient.username = username;
        SftpClient.password = password;
    }

    public SftpClient(String host, String username, String password, int port) {
        SftpClient.host = host;
        SftpClient.username = username;
        SftpClient.password = password;
        SftpClient.port = port;
    }

    public SftpClient(String host, String username, String password, int port, String privateKey, String passphrase) {
        SftpClient.host = host;
        SftpClient.username = username;
        SftpClient.password = password;
        SftpClient.privateKey = privateKey;
        SftpClient.passphrase = passphrase;
        SftpClient.port = port;
    }

    public static void connect() {
        JSch jsch = new JSch();
        Channel channel = null;
        try {
            if (!StringUtils.isEmpty(privateKey)) {
                // 使用密钥验证方式,密钥可以使有口令的密钥,也可以是没有口令的密钥
                if (!StringUtils.isEmpty(passphrase)) {
                    jsch.addIdentity(privateKey, passphrase);
                } else {
                    jsch.addIdentity(privateKey);
                }
            }
            sshSession = jsch.getSession(username, host, port);
            if (!StringUtils.isEmpty(password)) {
                sshSession.setPassword(password);
            }
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");// do not verify host
                                                            // key
            sshSession.setConfig(sshConfig);
            // session.setTimeout(timeout);
            // session.setServerAliveInterval(92000);
            sshSession.connect();
            // 参数sftp指明要打开的连接是sftp连接
            channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
        } catch (JSchException e) {
            logger.error("连接【" + host + ":" + port + "】异常", e);
        }
    }

    /**
     * 获取连接
     * @return channel
     */
    public void connectWithException() throws Exception {
        JSch jsch = new JSch();
        Channel channel = null;
        try {
            if (!StringUtils.isEmpty(privateKey)) {
                // 使用密钥验证方式,密钥可以使有口令的密钥,也可以是没有口令的密钥
                if (!StringUtils.isEmpty(passphrase)) {
                    jsch.addIdentity(privateKey, passphrase);
                } else {
                    jsch.addIdentity(privateKey);
                }
            }
            sshSession = jsch.getSession(username, host, port);
            if (!StringUtils.isEmpty(password)) {
                sshSession.setPassword(password);
            }
            Properties sshConfig = new Properties();
            // do not verify host key
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            // session.setTimeout(timeout);
            // session.setServerAliveInterval(92000);
            sshSession.connect();
            // 参数sftp指明要打开的连接是sftp连接
            channel = sshSession.openChannel("sftp");
            channel.connect();
            sftp = (ChannelSftp) channel;
        } catch (JSchException e) {
            logger.error("连接【" + host + ":" + port + "】异常", e);
            throw new Exception("Could not connect to :" + host + ":" + port);
        }
    }

    /**
     * 关闭资源
     */
    public static void disconnect() {
        if (sftp != null) {
            if (sftp.isConnected()) {
                sftp.disconnect();
            }
        }
        if (sshSession != null) {
            if (sshSession.isConnected()) {
                sshSession.disconnect();
            }
        }
    }

    /**
     * sftp is connected
     *
     * @return
     */
    public static boolean isConnected() {
        return sftp != null && sftp.isConnected();
    }

    public InputStream downFile(String remotePath, String remoteFile) throws Exception {
        try {
            if (sftp == null) {
                connect();
            }
            sftp.cd(remotePath);
            return sftp.get(remoteFile);
        } catch (SftpException e) {
            logger.error("文件下载失败或文件不存在!", e);
            throw e;
        } finally {
            // disconnect();
        }
    }

    public byte[] downLoad(String remotePath, String remoteFile) throws Exception {
        try {
            if (sftp == null) {
                connect();
            }
            sftp.cd(remotePath);
            InputStream input = sftp.get(remoteFile);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[10485760];
            int n = 0;
            while (-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
            }
            return output.toByteArray();
        } catch (SftpException e) {
            logger.error("文件下载失败或文件不存在!", e);
        } finally {
            disconnect();
        }
        return null;
    }



    /**
     * 下载单个文件
     *
     * @param remoteFileName
     *            下载文件名
     * @param localPath
     *            本地保存目录(以路径符号结束)
     * @param localFileName
     *            保存文件名
     * @return
     */
    public static synchronized boolean downloadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
        logger.info(remotePath + "/" + remoteFileName + "/" + localPath + "/" + localFileName);
        try {
            if (sftp == null || !isConnected()) {
                connect();
            }
            sftp.cd(remotePath);
            File file = new File(localPath + localFileName);
            mkdirs(localPath + localFileName);
            sftp.get(remoteFileName, new FileOutputStream(file));
            return true;
        } catch (FileNotFoundException e) {
            logger.error("不存在文件,Path:" + remotePath + ",file:" + remoteFileName, e);
        } catch (SftpException e) {
            logger.error("下载文件处理异常,Path:" + remotePath + ",file:" + remoteFileName, e);
        } finally {
            disconnect();
        }
        return false;
    }

    /**
     * 上传
     */
    public void uploadFile(String remotePath, String fileName, InputStream input) throws IOException, Exception {
        try {
            if (sftp == null) {
                connect();
            }
            // createDir(remotePath);
            mkDir(remotePath.replace(sftp.pwd(), ""));// 绝对路径变为相对路径
            sftp.put(input, fileName);
        } catch (Exception e) {
            logger.error("文件上传异常!", e);
            throw new Exception("文件上传异常:" + e.getMessage());
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (Exception e) {
                }
            }
            // disconnect();
        }
    }

    /**
     * 上传单个文件
     *
     * @param remotePath
     *            远程保存目录
     * @param remoteFileName
     *            保存文件名
     * @param localPath
     *            本地上传目录(以路径符号结束)
     * @param localFileName
     *            上传的文件名
     * @return
     */
    public boolean uploadFile(String remotePath, String remoteFileName, String localPath, String localFileName) {
        File fileInput = new File(localPath + localFileName);
        return uploadFile(remotePath, remoteFileName, fileInput);
    }

    /**
     * 上传单个文件
     *
     * @param remotePath
     *            远程保存目录
     * @param remoteFileName
     *            保存文件名
     * @param fileInput
     *            上传的文件
     * @return
     */
    public boolean uploadFile(String remotePath, String remoteFileName, File fileInput) {
        FileInputStream in = null;
        try {
            in = new FileInputStream(fileInput);
            uploadFile(remotePath, remoteFileName, in);
            return true;
        } catch (Exception e) {
            logger.error("上传单个文件异常", e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    logger.warn("关闭sftp资源异常", e);
                }
            }
        }
        return false;
    }

    /**
     * 创建目录
     *
     * @param createpath
     * @return
     */
    private boolean createDir(String createpath) {
        try {
            if (isDirExist(createpath)) {
                SftpClient.sftp.cd(createpath);
                return true;
            }
            String[] pathArry = createpath.split("/");
            StringBuffer filePath = new StringBuffer("/");
            for (String path : pathArry) {
                if (path.equals("")) {
                    continue;
                }
                filePath.append(path + "/");
                if (isDirExist(filePath.toString())) {
                    sftp.cd(filePath.toString());
                } else {
                    // 建立目录
                    sftp.mkdir(filePath.toString());
                    // 进入并设置为当前目录
                    sftp.cd(filePath.toString());
                }
            }
            return true;
        } catch (SftpException e) {
            logger.error("sftp创建目录异常", e);
        }
        return false;
    }

    /**
     * 判断目录是否存在
     *
     * @param directory
     * @return
     */
    public boolean isDirExist(String directory) {
        try {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            return sftpATTRS.isDir();
        } catch (Exception e) {
            // logger.error("sftp目录isDirExist异常", e);
        }
        return false;
    }

    /**
     * 如果目录不存在就创建目录
     *
     * @param path
     */
    private static void mkdirs(String path) {
        File f = new File(path);
        String fs = f.getParent();
        f = new File(fs);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    public boolean deleteFile(String remotePath, String remoteFile) throws Exception {
        try {
            if (sftp == null) {
                connect();
            }
            if (openDir(remotePath)) {
                sftp.rm(remoteFile);
            }
            return true;
        } catch (SftpException e) {
            logger.error("删除文件【" + remotePath + "/" + remoteFile + "】发生异常!", e);
            throw e;
        }
    }

    /**
     * 创建文件夹
     *
     * @param dirName
     */
    public void mkDir(String dirName) {
        String[] dirs = dirName.split("/");
        try {
            String now = sftp.pwd();
            for (int i = 0; i < dirs.length; i++) {
                if (StringUtils.isEmpty(dirs[i])) {
                    continue;
                }
                boolean dirExists = openDir(dirs[i]);
                if (!dirExists) {
                    sftp.mkdir(dirs[i]);
                    sftp.cd(dirs[i]);
                }
            }
            // 进入当前目录
            sftp.cd(now + "/" + dirName);
        } catch (SftpException e) {
            logger.error("mkDir Exception : " + e);
        }
    }

    /**
     * 打开文件夹一层一层
     *
     * @param directory
     * @return
     */
    public boolean openDir(String directory) {
        try {
            logger.debug("opendir: {}", directory);
            sftp.cd(directory);
            return true;
        } catch (SftpException e) {
            logger.debug("openDir【" + directory + "】 Exception : " + e);
            return false;
        }
    }

    /**
     * 获取输出的out put stream
     *
     * @param path
     * @param name
     * @return
     * @throws Exception
     */
    public OutputStream getUpLoadStream(String path, String name, String rcCode) throws Exception {
        if (sftp == null || !isConnected()) {
            connect();
        }
        String finalPath = path + rcCode;
        synchronized (CREATE_PATH_LOCK) {
            if (!openDir(finalPath)) {
                createDir(finalPath);
            }
        }
        sftp.cd(finalPath);
        return sftp.put(name);
    }

    private static Object CREATE_PATH_LOCK = new Object();

    public OutputStream getUpLoadStream(String path, String name) throws Exception {
        if (sftp == null || !isConnected()) {
            connect();
        }
        synchronized (CREATE_PATH_LOCK) {
            if (!openDir(path)) {
                createDir(path);
            }
        }
        sftp.cd(path);
        return sftp.put(name);
    }

    /**
     * 上传 不关闭任何流
     */
    public void uploadFileNotClose(InputStream input, String remotePath, String fileName) throws IOException, Exception {
        try {
            if (sftp == null) {
                connect();
            }
            if (!openDir(remotePath)) {
                createDir(remotePath);
            }
            sftp.put(input, fileName);
        } catch (Exception e) {
            logger.error("文件上传异常!", e);
            throw new Exception("文件上传异常:" + e.getMessage());
        }
    }

    /**
     * 上传(input上传完成,并未关闭,在外层调用处虚处理)
     */
    public void uploadFile(InputStream input, String remotePath, String fileName) throws IOException, Exception {
        try {
            if (sftp == null) {
                connect();
            }
            if (!openDir(remotePath)) {
                createDir(remotePath);
            }
            sftp.put(input, fileName);
        } catch (Exception e) {
            logger.error("文件上传异常!", e);
            throw new Exception("文件上传异常:" + e.getMessage());
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (Exception e) {
                }
            }
            disconnect();
        }
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        SftpClient.host = host;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        SftpClient.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        SftpClient.password = password;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        SftpClient.port = port;
    }

    public ChannelSftp getSftp() {
        return sftp;
    }

    public void setSftp(ChannelSftp sftp) {
        SftpClient.sftp = sftp;
    }

    @SuppressWarnings("unchecked")
    public Vector<ChannelSftp.LsEntry> listFiles(String remotePath) throws Exception {
        Vector<ChannelSftp.LsEntry> vector = null;
        try {
            if (sftp == null) {
                connect();
            }
            sftp.cd("/");
            vector = sftp.ls(remotePath);
        } catch (SftpException e) {
            throw new Exception("list file error.", e);
        }
        return vector;
    }

    /**
     * 判断文件是否存在
     * @param directory
     * @return
     */
    public boolean isFileExist(String directory) {
        boolean isDirExistFlag = false;
        try {
            if (sftp == null) {
                connect();
            }
            sftp.lstat(directory);
            isDirExistFlag = true;
        } catch (Exception e) {
            isDirExistFlag = false;
        }
        return isDirExistFlag;
    }

//    public static void main(String[] args){
//         downloadFile("/root/Desktop/remortFile/","123.txt","/Users/lss/Desktop/localPath/","abc.txt");
//
//    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt是一个跨平台的应用程序开发框架,可以用于开发各种类型的应用程序。Qt提供了QNetworkAccessManager类用于实现网络通信功能,包括上下载文件。 在Qt中实现SFTP下载功能,可以使用libssh2库进行操作。libssh2是一个用于实现SSH2协议的C语言库,可以对远程服务器进行认证、上下载文件等操作。 首先,需要在Qt项目中引入libssh2库。可以通过在.pro文件中添加LIBS += -lssh2指令来链接libssh2库。 接下来,可以创建一个SftpClient类来实现SFTP下载功能。在该类中,可以使用libssh2提供的API函数来连接远程SFTP服务器、进行认证、上下载文件。 上文件的步骤如下: 1. 使用libssh2_session_init函数初始化SSH2会话。 2. 使用libssh2_session_startup函数启动SSH2会话。 3. 使用libssh2_userauth_password函数使用用户名和密码进行认证。 4. 使用libssh2_scp_send64函数实现SFTP文件。 下载文件的步骤如下: 1. 使用libssh2_session_init函数初始化SSH2会话。 2. 使用libssh2_session_startup函数启动SSH2会话。 3. 使用libssh2_userauth_password函数使用用户名和密码进行认证。 4. 使用libssh2_scp_recv2函数实现SFTP下载文件。 在上下载过程中,可以使用Qt提供的QFile类来读取本地文件和写入本地文件。可以使用libssh2提供的相应函数来读取和写入远程文件。 需要注意的是,在进行SFTP下载之前,需要确保本地和远程的文件路径是正确的,并且具有相应的权限。 以上就是使用Qt实现SFTP下载的大致思路和步骤。具体的实现细节可以参考Qt和libssh2的官方文档和示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值