# Sftp文件上传和下载工具类

## 依赖

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





        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.21</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>

## 工具类SftpUtils

@Component
@Slf4j
public class SftpUtils {


public ChannelSftp sftp;
    public boolean isReady = false;
    public FtpConfig config;
    public Session sshSession;





    @Data
    private class FtpConfig {

        private String server;
        private String port;
        private String username;
        private String password;
        private String encoding;
    }







    /**
     * 连接sftp服务器
     */
    public SftpUtils(String server, String port, String username, String password, String encoding) {
        config = new FtpConfig();
        config.setServer(server);
        config.setPort(port);
        config.setUsername(username);
        config.setPassword(password);
        config.setEncoding(encoding);
        log.info("server = {}, port = {}, username = {}, password = {}", server, port, username, password);
    }





public void setReady() throws Exception {
        try {
            if (!isReady) {
                JSch jsch = new JSch();
                sshSession = jsch.getSession(config.getUsername(), config.getServer(), Integer.parseInt(config.getPort()));
                log.info("Session created.");
                sshSession.setPassword(config.getPassword());
                Properties sshConfig = new Properties();
                sshConfig.put("StrictHostKeyChecking", "no");
                sshSession.setConfig(sshConfig);
                isReady = true;
                log.info("Session is ready.");
            }
            if (sshSession != null && !sshSession.isConnected()) {
                sshSession.connect();
                Channel channel = sshSession.openChannel("sftp");
                channel.connect();
                sftp = (ChannelSftp) channel;
                Class<ChannelSftp> c = ChannelSftp.class;
                Field f = c.getDeclaredField("server_version");
                f.setAccessible(true);
                f.set(sftp, 2);
                sftp.setFilenameEncoding(config.getEncoding());
                log.info("Session is connected.");
            }
        } catch (Exception e) {
            this.close();
            log.error("sftp连接服务器出错,host:" + config.getServer(), e);
            throw e;
        }
    }






    /**
     * 判断目录是否存在
     * @param directory
     * @return
     */
    public boolean isDirExist(String directory)
    {
        boolean isDirExistFlag = false;
        try
        {
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            isDirExistFlag = true;
            return sftpATTRS.isDir();
        }
        catch (Exception e)
        {
            if (e.getMessage().equalsIgnoreCase("no such file"))
            {
                isDirExistFlag = false;
            }
        }finally {
            return isDirExistFlag;
        }
    }






    /**
     * 递归创建文件夹
     * @param createpath
     * @return
     */
    public boolean createDir(String createpath) {
        try
        {
            if (isDirExist(createpath))
            {
                this.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());
                }

            }
            this.sftp.cd(createpath);
            return true;
        }
        catch (SftpException e)
        {
            e.printStackTrace();
        }
        return false;
    }






    /**
     * 设置编码格式
     */
    public void setEncoding(){
        try {
            Class cl = sftp.getClass();
            Field field = cl.getDeclaredField("server_version");
            field.setAccessible(true);
            field.set(sftp,2);
            sftp.setFilenameEncoding("GBK");
        }catch (Exception e){
            e.printStackTrace();
        }

    }





    /**
     * 上传文件
     * @param filePath
     * @param fileName
     * @param file
     * @return
     * @throws Exception
     */
    public boolean uploadFile(String filePath, String fileName, File file) throws Exception {
        log.info("directory:{},downloadFile:{},saveFile:{}", filePath, fileName, file);
        try {
            setReady();
            // sftp.cd(filePath);
            sftp.put(new FileInputStream(file), fileName);
            return true;
        } catch (Exception e) {
            log.error("sftp上传文件出错,fileName:" + fileName, e);
            throw e;
        }
    }







    /**
     * 列出目录下的文件
     *
     * @param directory 文件所在目录
     * @throws Exception
     */
    public List<String> listFiles(String directory) throws Exception {
        log.info("directory:{}", directory);
        setReady();
        Vector<ChannelSftp.LsEntry> vector = sftp.ls(directory);
        if (vector.isEmpty()) {
            return Collections.emptyList();
        }
        return vector.stream().map(ChannelSftp.LsEntry::getFilename).collect(Collectors.toList()).stream().filter(file -> !".".equals(file) && !"..".equals(file)).collect(Collectors.toList());
    }





    /**
     * 删除文件
     *
     * @param directory
     *            要删除文件所在目录
     * @param deleteFile
     *            要删除的文件
     * @param sftp
     */
    public void delete(String directory, String deleteFile, ChannelSftp sftp) {
        try {
            sftp.cd(directory);
            sftp.rm(deleteFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }










}

## 压缩工具类

public class ZipUtil {


    /**
     * 将文件压缩成zip
     *
     * @param sourceFile 源文件或目录,如:archive.tar
     * @param targetFile 目标文件,如:archive.tar.zip
     */
    public static void compress(String sourceFile, String targetFile) {
        long d1 = System.currentTimeMillis();
        try (OutputStream fos = new FileOutputStream(targetFile);
             OutputStream bos = new BufferedOutputStream(fos);
             ArchiveOutputStream aos = new ZipArchiveOutputStream(bos);){
            Path dirPath = Paths.get(sourceFile);
            Files.walkFileTree(dirPath, new SimpleFileVisitor<Path>() {
                @Override
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                    ArchiveEntry entry = new ZipArchiveEntry(dir.toFile(), dirPath.relativize(dir).toString());
                    aos.putArchiveEntry(entry);
                    aos.closeArchiveEntry();
                    return super.preVisitDirectory(dir, attrs);
                }

                @Override
                public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                    ArchiveEntry entry = new ZipArchiveEntry(
                            file.toFile(), dirPath.relativize(file).toString());
                    aos.putArchiveEntry(entry);
                    IOUtils.copy(new FileInputStream(file.toFile()), aos);
                    aos.closeArchiveEntry();
                    return super.visitFile(file, attrs);
                }
            });
        } catch (IOException e) {
            System.out.println("压缩失败,原因:" + e.getMessage());
        }
        System.out.println("压缩完毕,耗时:" + (System.currentTimeMillis() - d1) + " ms");
    }




























}

## 测试类

@Slf4j
public class SftpTest {


@Test
    public void uploadTest() throws IOException {
        SftpUtils sftpUtils = new SftpUtils("IP", "port", "username", "password", "UTF-8");
        try {
            sftpUtils.setReady();

            // 本地目录
            String localPath = ("D:"+ File.separator + "game" + File.separator);
            // 文件名称
            String fileName = "植物大战僵尸";
            // 服务器目录
            // String sftpPath = ("File.separator" + "opt" + "File.separator" + "pvz" + "File.separator ");
            String sftpPath = ("/" + "opt" + "/" + "pvz" + "/");
            // 文件格式
            String suffix = ".zip";


            String localFilePath = localPath + fileName + suffix;

            String sftpFilePath = sftpPath + fileName + suffix;

            String localFolder = localPath + fileName;

            log.info("local:" + localFilePath);

            log.info("sftp:" + sftpFilePath);


            // 本地文件
            File file = new File(localFilePath);

            File fileFolder = new File(localFolder);


            // 文件不存在则压缩文件
            if (file.exists()){
                boolean deleteFlag = file.delete();
                if (deleteFlag){
                    log.info("删除成功!");
                }else {
                    throw new Exception("删除失败!");
                }
            }

            // 文件夹存在则压缩文件夹
            if (fileFolder.exists()){
                ZipUtil.compress(localFolder , localFilePath);
            }else {
                throw new Exception("文件夹不存在,请确认!");
            }


            // 设置编码格式
            sftpUtils.setEncoding();


            // 判断服务器是否需要创建文件夹
            if (sftpUtils.isDirExist(sftpPath,sftpUtils.sftp)){
                sftpUtils.sftp.cd(sftpPath);
            }else {
                sftpUtils.createFolder(sftpPath);
            }


            // 删除服务器上的旧文件
            sftpUtils.delete(sftpPath,fileName,sftpUtils.sftp);



            // 展示文件
            List<String> fileList1 = sftpUtils.listFiles(sftpPath);
            log.info("上传前目录列表:");
            fileList1.forEach(System.out::println);
            // System.out.println("上传前服务器文件:");
            // for (String f:fileList1){
            //     System.out.println(f);
            // }

            // 上传
            boolean result = sftpUtils.uploadFile(localFilePath,fileName + suffix,file);


            // 展示文件
            List<String> fileList2 = sftpUtils.listFiles(sftpPath);
            System.out.println("上传后目录列表:");
            fileList2.forEach(System.out::println);
            // for (String f:fileList2){
            //     System.out.println(f);
            // }


            if (result){
                log.info("上传成功!");
            }else {
                log.info("上传失败!");
            }



        }catch (Exception e){
            log.error(e.getMessage());
        }finally {
            sftpUtils.close();
        }
    }



























}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值