事情背景: 最开始我是使用的hutool的工具类ftp, maven依赖
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.9</version></dependency><dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.8.0</version></dependency>
然后我最开始错误的初始化的部分是这样的
url = new URL("ftp://" + config.getUrl()); int port = url.getPort() == -1 ? 21 : url.getPort();Ftp ftp = new Ftp(new FtpConfig(url.getHost(), port, config.getUser(), config.getPassword(), CharsetUtil.CHARSET_UTF_8), FtpMode.Passive);ftp.getClient().setFileType(FTPClient.BINARY_FILE_TYPE);ftp.getClient().setAutodetectUTF8(true);ctx.setFtp(ftp);
遇到的问题:遇到一个中文乱码的,下载不了。
图示:
服务端utf-8 <----> 客户端 utf-8 √
服务端ISO-8859-1 <----> 客户端 ISO-8859-1 √
服务端ISO-8859-1 <----> 客户端 GBK ×
解决办法:1 、首先弃用了hutool的工具类。因为 client.setAutodetectUTF8(true);
这个方法的注释说明了,要在连接前调用,而hutool的初始化方法中,可以传指定的字符集,但是调用setAutodetectUTF8 已经是在连接之后了。
2、ftp服务器默认的编码是ISO-8859-1,net包初始化的 new FTPClient()默认的也是ISO-8859-1,如果都是ISO-8859-1 可以正常传文件,但是名字是乱码的,可以使用CharsetUtil.convert(name,CharsetUtil.CHARSET_ISO_8859_1,CharsetUtil.CHARSET_GBK)
转成GBK即可。
3、如果服务器不支持utf-8,那么默认的编码是ISO-8859-1,那么使用client.setControlEncoding(CharsetUtil.GBK)
istFiles得到的是中文,但是调用listFiles, changeWorkingDirectory,retrieveFileStream 传入的参数还必须是转成ISO-8859-1
4、如果全部都设置成utf-8 也是正确的。开启自动检 client.setAutodetectUTF8(true);
如果是支持utf-8的,客户端和服务端都用utf-8,不会出错;
if (FTPReply.isPositiveCompletion(client.sendCommand("OPTS UTF8", "ON"))) {log.info("开启ftp utf-8编码");// 支持UTF-8字符集client.setControlEncoding(CharsetUtil.UTF_8);} ```