如题,或者说 FTP 服务端编码不确定的情况下如何保证不会乱码
吾辈在项目中使用 jsch
连接 SFTP,然而使用 ls
获取文件列表中的中文文件名都乱码了,而且参数为中文文件名的时候会直接抛出异常 no such file
代码如下
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();
}
}
}
}
已经尝试的解决方案有:
- 使用
sftp.setFilenameEncoding("UTF-8");
设置文件名编码为UTF-8
:实测无效 - 使用
sftp.setFilenameEncoding("GBK");
:抛出异常com.jcraft.jsch.SftpException: The encoding can not be changed for this sftp server.
- 使用
sftp.ls(new String("/测试中文目录".getBytes("GBK"), "ISO-8859-1"))
编码文件名,抛出异常com.jcraft.jsch.SftpException: No such file
有人遇到过这种问题么?
遇到同样问题,题主有解决吗