We use jsch
to connect to SFTP in the project, but using ls
to get the Chinese file names in the file list is garbled, and if the parameter is Chinese file name, we will directly throw an exception no such file
the code is as follows
package com.zx.idc.common.ftp.sftp;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
import java.util.Vector;
import java.util.stream.Collectors;
/**
* @author rxliuli
*/
public class SftpTest {
private final Logger log = LoggerFactory.getLogger(getClass());
@Test
public void ls() {
final JSch jSch = new JSch();
ChannelSftp sftp = null;
Session session = null;
try {
session = jSch.getSession("rxliuli", "localhost", 22);
session.setPassword("123456");
final Properties properties = new Properties();
properties.put("StrictHostKeyChecking", "no");
session.setConfig(properties);
session.connect();
log.info("JSch open ssh session successful: {}", session);
sftp = (ChannelSftp) session.openChannel("sftp");
sftp.connect();
/*
GBK
com.jcraft.jsch.SftpException: The encoding can not be changed for this sftp server.
*/
sftp.setFilenameEncoding("UTF-8");
log.info("Sftp connection successful: {}", sftp);
/*
:
TestSftpDir
.xsd
*/
final Vector<ChannelSftp.LsEntry> list = sftp.ls("/");
log.info("list: \n{}", list.stream().map(ChannelSftp.LsEntry::getFilename).collect(Collectors.joining("\n")));
/*
:
com.jcraft.jsch.SftpException: No such file
*/
try {
sftp.ls("/");
} catch (SftpException sftpException) {
sftpException.printStackTrace();
}
/*
:
com.jcraft.jsch.SftpException: No such file
*/
try {
sftp.ls(new String("/".getBytes("GBK"), "ISO-8859-1"));
} catch (SftpException sftpException) {
sftpException.printStackTrace();
}
} catch (Throwable e) {
log.error("sftp operation failed: {}", e);
throw new RuntimeException(e);
} finally {
if (sftp != null && sftp.isConnected()) {
sftp.disconnect();
}
if (session != null && session.isConnected()) {
session.disconnect();
}
}
}
}
the solutions that have been tried are:
- use
sftp.setFilenameEncoding ("UTF-8");
set the file name encoding toUTF-8
: invalid measured - use
sftp.setFilenameEncoding ("GBK");
: throw an exceptioncom.jcraft.jsch.SftpException: The encoding can not be changed for this sftp server.
- use
sftp.ls (new String ("/ test Chinese directory" .getBytes ("GBK"), "ISO-8859-1")
encode the file name, and throw an exceptioncom.jcraft.jsch.SftpException: No such file
has anyone ever encountered this problem?