0
点赞
收藏
分享

微信扫一扫

java jsch sftp 中文乱码解决方案

不同 jsch 版本对比 ---> Java SSH/Sftp 库 —— JSch/SSHJ

方案一:

maven版本:

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

代码案例:

package com.chinaunicom.eworkorder.util;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Stack;

@Slf4j
@Component
public class SFTPUtils {
    @Value("${sftp.host}")
    public String host;

    @Value("${sftp.username}")
    public String username;

    @Value("${sftp.password}")
    public String password;

    @Value("${sftp.port}")
    public Integer port;

    @Value("${sftp.path}")
    public String path;

    private Session session;

    public ChannelSftp getSFTPChannel() {
        return getSFTPChannel(host, username, password, port);
    }

    public ChannelSftp getSFTPChannel(String sftpHost, String sftpUserName, String sftpPassword, int sftpPort) {
        

        if (session != null && session.isConnected()) {
            try {
                ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
                Class classInfo = ChannelSftp.class;
                Field field = classInfo.getDeclaredField("server_version");
                field.setAccessible(true);
                field.set(sftpChannel, 2);
                sftpChannel.setFilenameEncoding("GBK"); // 设置中文编码
                return sftpChannel;
            } catch (JSchException  | NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        try {
            JSch jsch = new JSch();
            session = jsch.getSession(sftpUserName, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftpChannel = (ChannelSftp) channel;
            Class classInfo = ChannelSftp.class;
            Field field = classInfo.getDeclaredField("server_version");
            field.setAccessible(true);
            field.set(sftpChannel, 2);
            sftpChannel.setFilenameEncoding("GBK"); // 设置中文编码
            return sftpChannel;
        } catch (JSchException | SftpException | NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param remoteFilePath 远程文件路径
     * @param localFilePath  本地文件路径
     */
    public void downloadFile(String remoteFilePath, String localFilePath) {
        log.info("sftp 下载文件 远程路径: {}, 本地文件路径:{}", remoteFilePath, localFilePath);
        ChannelSftp sftp = getSFTPChannel();
        try {
            // 创建本地路径的目录
            String localDir = localFilePath.substring(0,
                    Math.max(localFilePath.lastIndexOf("/"), localFilePath.lastIndexOf("\\")));
            File localDirFile = new File(localDir);
            if (!localDirFile.exists()) {
                localDirFile.mkdirs();
            }

            sftp.get(path + remoteFilePath, localFilePath);
        } catch (SftpException e) {
            log.info("下载文件失败: {}",e.getMessage());
            e.printStackTrace();
        } finally {
            closeSFTPChannel();
        }
    }



    /**
     * 上传文件
     *
     * @param localFilePath  本地文件路径
     * @param remoteFilePath 远程文件路径
     */
    public void uploadFile(String localFilePath, String remoteFilePath) {
        log.info("sftp 上传文件 远程路径: {}, 本地文件路径:{}", remoteFilePath, localFilePath);
        ChannelSftp sftp = getSFTPChannel();
        try {
            // 获取远程文件路径的目录
            String remoteDir = path + remoteFilePath.substring(0,
                    Math.max(remoteFilePath.lastIndexOf("/"), remoteFilePath.lastIndexOf("\\")));
            // 创建远程路径
            try {
                sftp.stat(remoteDir);
            } catch (SftpException e) {
                // 路径不存在,需要创建
                createRemoteDirectory(sftp, remoteDir);
            }
            // 上传文件
            sftp.put(localFilePath, path + remoteFilePath);
        } catch (SftpException e) {
            log.info("上传文件文件失败: {}",e.getMessage());
            e.printStackTrace();
        } finally {
            closeSFTPChannel();
        }
    }

    private static void createRemoteDirectory(ChannelSftp sftp, String remoteDir) throws SftpException {
        Stack<String> stack = new Stack<>();
        String dir = remoteDir;
        while (true) {
            try {
                sftp.stat(dir);
                break;
            } catch (SftpException e) {
                stack.push(dir);
                dir = dir.substring(0, Math.max(dir.lastIndexOf("/"), dir.lastIndexOf("\\")));
            }
        }
        while (!stack.isEmpty()) {
            String dirToCreate = stack.pop();
            sftp.mkdir(dirToCreate);
        }
    }


    public void closeSFTPChannel() {
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
    }

}


方案二:

maven版本:

<dependency>
   <groupId>com.github.mwiede</groupId>
   <artifactId>jsch</artifactId>
   <version>0.2.10</version>
</dependency>

代码案例:

package com.chinaunicom.eworkorder.util;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import sun.nio.cs.ext.GBK;

import java.io.File;
import java.util.Stack;


@Slf4j
@Component
public class SFTPUtils {
    @Value("${sftp.host}")
    public String host;

    @Value("${sftp.username}")
    public String username;

    @Value("${sftp.password}")
    public String password;

    @Value("${sftp.port}")
    public Integer port;

    @Value("${sftp.path}")
    public String path;

    private Session session;

    public ChannelSftp getSFTPChannel() {
        return getSFTPChannel(host, username, password, port);
    }

    public ChannelSftp getSFTPChannel(String sftpHost, String sftpUserName, String sftpPassword, int sftpPort) {


        if (session != null && session.isConnected()) {
            try {
                ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
                sftpChannel.setFilenameEncoding(new GBK());
                return sftpChannel;
            } catch (JSchException e) {
                e.printStackTrace();
            }
        }

        try {
            JSch jsch = new JSch();
            session = jsch.getSession(sftpUserName, sftpHost, sftpPort);
            session.setPassword(sftpPassword);
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();

            Channel channel = session.openChannel("sftp");
            channel.connect();
            ChannelSftp sftpChannel = (ChannelSftp) channel;
            sftpChannel.setFilenameEncoding(new GBK());
            return sftpChannel;
        } catch (JSchException  e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param remoteFilePath 远程文件路径
     * @param localFilePath  本地文件路径
     */
    public void downloadFile(String remoteFilePath, String localFilePath) {
        log.info("sftp 下载文件 远程路径: {}, 本地文件路径:{}", remoteFilePath, localFilePath);
        ChannelSftp sftp = getSFTPChannel();
        try {
            // 创建本地路径的目录
            String localDir = localFilePath.substring(0,
                    Math.max(localFilePath.lastIndexOf("/"), localFilePath.lastIndexOf("\\")));
            File localDirFile = new File(localDir);
            if (!localDirFile.exists()) {
                localDirFile.mkdirs();
            }
            sftp.get(path + remoteFilePath, localFilePath);
        } catch (SftpException e) {
            log.info("下载文件失败: {}",e.getMessage());
            e.printStackTrace();
        } finally {
            closeSFTPChannel();
        }
    }

    /**
     * 上传文件
     *
     * @param localFilePath  本地文件路径
     * @param remoteFilePath 远程文件路径
     */
    public void uploadFile(String localFilePath, String remoteFilePath) {
        log.info("sftp 上传文件 远程路径: {}, 本地文件路径:{}", remoteFilePath, localFilePath);
        ChannelSftp sftp = getSFTPChannel();
        try {
            // 获取远程文件路径的目录
            String remoteDir = path + remoteFilePath.substring(0,
                    Math.max(remoteFilePath.lastIndexOf("/"), remoteFilePath.lastIndexOf("\\")));
            // 创建远程路径
            try {
                sftp.stat(remoteDir);
            } catch (SftpException e) {
                // 路径不存在,需要创建
                createRemoteDirectory(sftp, remoteDir);
            }
            // 上传文件
            sftp.put(localFilePath, path + remoteFilePath);
        } catch (SftpException e) {
            log.info("上传文件文件失败: {}",e.getMessage());
            e.printStackTrace();
        } finally {
            closeSFTPChannel();
        }
    }

    private static void createRemoteDirectory(ChannelSftp sftp, String remoteDir) throws SftpException {
        Stack<String> stack = new Stack<>();
        String dir = remoteDir;
        while (true) {
            try {
                sftp.stat(dir);
                break;
            } catch (SftpException e) {
                stack.push(dir);
                dir = dir.substring(0, Math.max(dir.lastIndexOf("/"), dir.lastIndexOf("\\")));
            }
        }
        while (!stack.isEmpty()) {
            String dirToCreate = stack.pop();
            sftp.mkdir(dirToCreate);
        }
    }


    public void closeSFTPChannel() {
        if (session != null && session.isConnected()) {
            session.disconnect();
        }
    }

}
举报

相关推荐

0 条评论