首页 > 编程语言 >java jsch sftp 中文乱码解决方案

java jsch sftp 中文乱码解决方案

时间:2023-08-01 17:03:47浏览次数:41  
标签:jsch remoteFilePath java String sftp 乱码 session localFilePath public

不同 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();
        }
    }

}

标签:jsch,remoteFilePath,java,String,sftp,乱码,session,localFilePath,public
From: https://blog.51cto.com/learningfish/6924497

相关文章

  • 从Java后端获取时间配置字符串,并在前端使用它来设置默认公布时间。
    <divclass="layui-inline"id="AItem"><labelclass="layui-form-labelsyn-form-item-require">公布时间:</label><divclass="layui-input-block">&......
  • 学习Java的第11天
    运算符算数运算符:+,-,*,/,%,++,--赋值运算符:=关系运算符:>,<,>=,<=,==,!=instanceof逻辑运算符:&&,||,!位运算符:&,|,^,~,>>,<<,>>>(了解!!!)条件运算符?:扩展赋值运算符:+=,-=,*=,/=packageoperator;publicclassDemo03{publicstaticv......
  • 学生信息管理小系统(Java)
    一、题目要求 需要实现对应的操作二、思路(1)先设计一个主菜单界面,用户可以选择对应的功能;(2)每个板块对应一个方法,实现具体的操作;(3)最后在main函数中使用switch方法根据用户的选择对应不同的结果;三、代码1importjava.util.ArrayList;2importjava.util.Scanner;3......
  • JavaScript基础02
    隐式类型转换加法运算中,如果参与运算的有一个值不是数字,另外一个值是数字,会将数字隐式转换成字符串再与数字进行拼接减乘除取余运算中,如果有非数字,会将它隐式转成数值,然后参与运算;如果参与运算存在NaN,那么得到的是NaN运算符算术运算符+-*/%一元运算符++自增--自......
  • java并发之锁的升级
    偏向锁-->轻量级锁-->重量级锁,是synchronized的三种形态转换。 锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率。 线程的状态:就绪队列可能随时被CPU选中执行;阻塞队列需要等其他......
  • Java之String系列--String, StringBuffer, StringBuilder区别
    简介本文介绍Java的String,StringBuffer,StringBuilder的区别。项StringStringBufferStringBuffer线程安全性不可变。原因:value数组是final类型。因为不可变,所以每次操作生成新对象。因为不可变,所以每次操作生成新对象。原因:value数组是final类型。原因:其父类(AbstractStringBuilder......
  • Java实现读取Excel文件并逐行写入到新的Excel文件中
    在日常开发中,经常需要处理Excel文件,其中一种常见的需求是将原始Excel文件的内容逐行写入到新的Excel文件中或者写入数据中。本篇博客将介绍使用Java编程语言以及ApachePOI库来实现这一功能。ApachePOI是一个开源的Java库,用于处理MicrosoftOffice格式的文件,包括Excel。1.环境......
  • javase学习文档
      javase学习文档(更新)javase学习文档已更新查看地址:https://talentestors.gitee.io/my-notes/codenotes/javase/......
  • IDEA中Tomcat输出乱码
    新安装的IDEA,控制台输出Tomcat日志乱码网上有很多方法,如idea启动Tomcat时控制台出现乱码的解决(亲测有效)因为我之前的IDEA使用没问题,应该就是新安装IDEA问题,在设置中搜索“encoding”,把所有搜出来的选项设为UTF-8,其中下面这条有效果如果不清楚哪里有问题,就把上面链接里的所......
  • Java导入、导出excel
    Excel是由四个元素组成的分别是:WorkBook(工作簿)、Sheet(工作表)、Row(行)、Cell(单元格),其中包含关系是从左至右,一个WorkBook可以包含多个Sheet,一个Sheet又是由多个Row组成,一个Row是由多个Cell组成。1.1创建Excel的元素1)创建WokrBookWorkbook workbook = new XSSFWorkboo......