leodengzx 2020-01-04
private static String LOCAL_CHARSET = "GBK"; // FTP协议中规定的文件名编码为: iso-8859-1 private static String FTP_CHARSET = "ISO-8859-1"; ... if (ftpClient.login(user, pwd)) { if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) { // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8,否则使用本地编码(GBK) LOCAL_CHARSET = "UTF-8"; } ftpClient.setControlEncoding(LOCAL_CHARSET); // 设置被动模式 ftpClient.setLocalPassiveMode(); ... } ftpClient.changeWorkingDirectory(encodingServerPath(remotePath)) // 上传的时候使用 ftpClient.storeFile(encodingServerPath(fileName), inputStream); /** * 编码文件路径 */ private static String encodingServerPath(String path) throws UnsupportedEncodingException { // FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码,replace处理文件路径 return new String(path.replace("\\", "/").replaceAll("//", "/").getBytes(LOCAL_CHARSET), FTP_CHARSET); } // 下载的时候使用 ftpClient.retrieveFile(encodingServerPath(fileName), outputStream); // 打印ftp工作目录时需要切换转码 System.out.println("当前工作目录:"+ new String(ftp.printWorkingDirectory().getBytes(FTP_CHARSET), LOCAL_CHARSET));
filePath 的原始编码: origin_charset => start java后台: new String(filePath.getBytes(Local_CHARSET), "ISO-8859-1") => step_1 FTP Protocol: new String(filePath.getBytes("ISO-8859-1"), FTP_CHARSET) => step_2 FTP 服务器的默认编码: new String(filePath.getBytes(FTP_CHARSET), server_charset) => end if(Local_CHARSET == FTP_CHARSET) upload正常, else upload异常(无法创建和切换目录) if(origin_charset == server_charset) 文件名在FTP服务器上显示正常, else 文件在FTP服务器显示乱码,download异常 如果filePath的编码与上传是的编码不一致,download异常
测试后的代码托管在GitHub中,地址https://github.com/Hlingoes/file-message-server,位于application/FtpService中,供参考和提出改进建议