使用代码自动化话操作sftp服务器

package cn.weblab.plugin.util;

import com.intellij.openapi.progress.ProgressIndicator;
import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;

import java.io.*;
import java.util.Properties;
import java.util.UUID;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class SFTPUtil {
    Session session = null;
    Channel channel = null;
    final String sftpHost = "XXXXXXXXXX";
    final String sftpUsername = "XXXXXXXX";
    final String sftpPassword = "XXXXXXX";
    final int sftpPort = 22;
    Long originSize;

    /**
     * 获取sftp channel对象
     *
     * @return
     * @throws JSchException
     */
    public ChannelSftp getChannelSftp() throws JSchException {
        // 创建JSch对象
        JSch jsch = new JSch();
        // 获取sesson对象
        session = jsch.getSession(sftpUsername, sftpHost, sftpPort);
        // 设置sftp访问密码
        session.setPassword(sftpPassword);
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        // 为session重新设置参数
        session.setConfig(config);
        // 设置超时
        session.setTimeout(30000);
        session.connect();
        // 打开sftp通道
        channel = session.openChannel("sftp");
        // 建立sftp通道连接
        channel.connect();
        return (ChannelSftp) channel;
    }

    public void closeChannel() {
        if (channel != null) {
            channel.disconnect();
            System.out.println("断开channel");
        }
        if (session != null) {
            session.disconnect();
            System.out.println("断开session");
        }
    }

    public static void main_1(String[] args) throws JSchException, SftpException {

        /**
         * JSch支持三种文件传输模式:
         * OVERWRITE 完全覆盖模式,这是JSch的 默认
         * 文件传输模式,即如果目标文件已经存在,传输的文件将完全覆盖目标文件,产生新的文件。
         * RESUME 恢复模式,如果文件已经传输一部分,这时由于网络或其他任何原因导致文件传输中断,如果下一次传输相同的文件,
         * 则会从上一次中断的地方续传。
         * APPEND 追加模式,如果目标文件已存在,传输的文件将在目标文件后追加。
         */
        SFTPUtil sftpChannel = new SFTPUtil();
        ChannelSftp channel = sftpChannel.getChannelSftp();
        channel.get("/fileSys/sftp/711997c9-bdc5-47ea-9b98-a360809f585f", "C:\\Users\\陈景涛\\Desktop\\fsdownload");
        // String srcDirectory = "E:\\code\\java\\plugin-second\\", destDirectory = "/fileSys/sftp/" + UUID.randomUUID().toString();
        // sftpChannel.chuanshu(channel, srcDirectory, destDirectory, indicator, 0L);
        // channel.quit();
        // sftpChannel.closeChannel();
        // System.out.println(channel.pwd());


    }

    public static void upload(String srcFilePath, String destFilePath, ProgressIndicator indicator) throws JSchException {
        System.err.println("upload is called");
        SFTPUtil sftpUtil = new SFTPUtil();
        sftpUtil.setOriginSize(calcSize(new File(srcFilePath)));
        ChannelSftp channel = sftpUtil.getChannelSftp();
        Long[] arr = new Long[1];
        arr[0] = 0L;
        sftpUtil.chuanshu(channel, srcFilePath, destFilePath, indicator, arr);
        return;
    }

    /**
     * 向服务器指定目录下以覆盖模式传输文件|文件夹
     *
     * @param channel     sftp通道对象
     * @param srcFilePath 源文件[目录]路径, 可为文件或文件目录
     * @return
     * @author yuguagua
     * @email feimeideyanggao@126.com
     * @create 2021年2月6日
     * @destFilePath 目标文件夹目录, 必须存在在且必须为目录!!!不可以是文件!!!, 后缀不要加 / , 传输的文件夹会新建在此目录下
     */
    public void chuanshu(ChannelSftp channel, String srcFilePath, String destFilePath, ProgressIndicator indicator, Long[] tmp) {
        try {
            channel.cd(destFilePath);
        } catch (SftpException e) {
            System.out.println("目标文件夹不存在,开始创建");
            try {
                channel.mkdir(destFilePath);
            } catch (SftpException sftpException) {
                System.out.println("创建目标文件夹失败");
                return;
            }
        }
        File file = new File(srcFilePath);
        String subDestFilePath = destFilePath + "/" + file.getName(); // 真·文件目录
        // 1. 源文件为目录, 则列表显示其下所有的文件夹、文件
        if (file.isDirectory()) {
            // 1.1 在destFilePath目录下检查本目录是否存在, 存在则删除再创建; 不存在则新创建
            try {
                channel.cd(subDestFilePath);
                System.out.println("目标服务器上 目录: " + subDestFilePath + " 存在, 先予以删除");
                channel.cd(destFilePath);
                deleteTargetFile(channel, subDestFilePath);
                System.out.println("目标服务器上 目录: " + subDestFilePath + " 删除成功");
                channel.mkdir(subDestFilePath);
                System.out.println("目标服务器上 目录: " + subDestFilePath + " 删除后创建成功");
            } catch (SftpException e) {
                System.out.println("目标服务器上 目录: " + subDestFilePath + " 不存在, 正在创建");
                try {
                    channel.mkdir(subDestFilePath);
                } catch (SftpException e1) {
                    System.out.println("目标服务器上 创建目录: " + subDestFilePath + " 出错." + e1.getLocalizedMessage());
                }
            }
            File subfiles[] = file.listFiles();
            for (int i = 0; i < subfiles.length; i++) {
                chuanshu(channel, subfiles[i].getAbsolutePath(), subDestFilePath, indicator, tmp);
            }
        } else {

            // 2. 源文件为文件,将文件传输到 destFilePath目录下
            // 2.1 检查destFilePath目录是否存在, 不存在则创建
            try {
                channel.cd(destFilePath);
            } catch (SftpException e) {
                System.out.println("目录: " + destFilePath + " 不存在, 正在创建");
                try {
                    channel.mkdir(destFilePath);
                } catch (SftpException e1) {
                    System.out.println("创建目录: " + destFilePath + " 出错." +
                            e1.getLocalizedMessage());

                }
            }
            try {
                channel.cd(destFilePath);
                channel.put(srcFilePath, destFilePath + "/" + file.getName(), ChannelSftp.OVERWRITE);
                long length = new File(srcFilePath).length();
                tmp[0] += length;
                System.out.println(tmp[0] + "-------->" + tmp[0] / (double) originSize);
                indicator.setFraction(tmp[0] / (double) originSize);
                System.out.println("传输文件: " + srcFilePath + "  到  " + destFilePath + "/" + file.getName() + "  成功.");
            } catch (SftpException e) {
                System.out.println("传输文件: " + srcFilePath + "  到  " + destFilePath + "/" + file.getName() + "  出错."
                        + e.getLocalizedMessage());
            }
        }

    }

    /**
     * 删除服务器指定的文件夹及其里面的所有内容
     *
     * @param targetFilePath 要删除的文件或文件夹路径, 应为绝对路径, 且非空
     * @return
     * @author yuguagua
     * @email feimeideyanggao@126.com
     * @create 2021年2月6日
     */
    public void deleteTargetFile(ChannelSftp channel, String targetFilePath) {
        try {
            // 1. 路径为文件夹
            if (channel.stat(targetFilePath).isDir()) {
                channel.cd(targetFilePath);
                Vector<LsEntry> entries = channel.ls(".");
                for (LsEntry subFilePath : entries) {
                    String fileName = subFilePath.getFilename();
                    if (".".equals(fileName) || "..".equals(fileName)) {
                        continue;
                    }
                    deleteTargetFile(channel, subFilePath.getFilename());
                }
                channel.cd("..");
                channel.rmdir(targetFilePath);
                System.out.println("删除文件夹: " + targetFilePath + " 成功. ");
            } else {
                // 2. 路径为文件
                try {
                    channel.rm(targetFilePath);
                    System.out.println("删除文件: " + targetFilePath + " 成功. ");
                } catch (SftpException e) {
                    System.out.println("删除文件: " + targetFilePath + " 出错. " + e.getMessage());
                }
            }
        } catch (SftpException e) {
            System.out.println("判断文件: " + targetFilePath + " 类型出错. " + e.getMessage());
        }

    }

    public static long calcSize(File file) {
        if (file.isFile()) {
            return file.length();
        }
        long num = 0;
        File[] subFiles = file.listFiles();
        for (File subFile : subFiles) {
            if (subFile.isFile()) {
                System.out.println(subFile.getAbsolutePath() + "---->" + subFile.length());
                num += subFile.length();
            } else {
                num += calcSize(subFile);
            }
        }
        return num;
    }

    public void uploadSingleFile(byte[] data, String destinationDir, String fileName) throws Exception {
        fileName += ".tar.gz";
        SFTPUtil sftpUtil = new SFTPUtil();
        ChannelSftp channel = sftpUtil.getChannelSftp();
        // 获取输入流
        InputStream input = new ByteArrayInputStream(data);
        long start = System.currentTimeMillis();
        try {
            //如果文件夹不存在,则创建文件夹
            //切换到指定文件夹
            channel.cd(destinationDir);
        } catch (SftpException e) {
            //创建不存在的文件夹,并切换到文件夹
            channel.mkdir(destinationDir);
            channel.cd(destinationDir);
        }
        channel.put(input, fileName);
        System.out.println("文件上传成功!! 耗时:{" + (System.currentTimeMillis() - start) + "}ms");

    }

    public static byte[] getAllBytes(File file) throws Exception {
        ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();
        FileInputStream inputStream = new FileInputStream(file);
        byte[] buf = new byte[1024];
        int len;
        while ((len = inputStream.read(buf)) > 0) {
            byteArrayOs.write(buf, 0, len);
        }
        return byteArrayOs.toByteArray();
    }

    public static byte[] getAllBytesWithSchedule(File file, ProgressIndicator indicator) throws Exception {
        long fileLength = file.length();
        ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();
        FileInputStream inputStream = new FileInputStream(file);
        byte[] buf = new byte[1024];
        int len;
        long sum = 0;
        while ((len = inputStream.read(buf)) > 0) {
            byteArrayOs.write(buf, 0, len);
            sum += len;
            indicator.setFraction((sum / fileLength) / 1.5);
        }
        return byteArrayOs.toByteArray();
    }

    public Long getOriginSize() {
        return originSize;
    }

    public void setOriginSize(Long originSize) {
        this.originSize = originSize;
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值