完全解决FTP上传文件名称中文乱码问题
创始人
2025-01-19 09:33:43
0

完全解决FTP上传文件名称中文乱码问题

    • 说明
      • 无效踩坑经历
    • 有效解决方法
    • 定时上传文件至ftp样例

说明

今天项目上加了个定时扫描本地文件路径下所有文件实现自动上传至ftp文件服务器的功能,经测试发现一旦上传中文名称的文件就会乱码或者文件上传不了。初步排查就是FTP服务器字符编码的问题。在网上查了很多资料都没有效果。在这里讲一下我踩过的坑,以及分享我能上传成功的样例。

无效踩坑经历

  • 踩坑1(说明:不一定无效,但是我试了不行)
    本地文件名进行 (UTF-8 ,GBK) 和 ISO-8859-1 的转换
 public static String encodingUTF8(String path) throws UnsupportedEncodingException {         return new String(path.getBytes("UTF-8"), "ISO-8859-1");     }      public static String encodingGBK(String path) throws UnsupportedEncodingException {         return new String(path.getBytes("GBK"), "ISO-8859-1");     }      
  • 踩坑2(说明:不一定无效,但是我试了不行)
    打开IIS服务器,然后找到FTP服务,选择高级配置,把允许utf8改成false

请添加图片描述

有效解决方法

思路:设置ftp支持UTF-8, ftpClient.sendCommand(“OPTS UTF8”, “ON”),核心代码如下

//链接至ftp服务器,设置编码格式  Ftp ftp = new Ftp(url, 21, username, password); //开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就用本地编码(ISO-8859-1) if (FTPReply.isPositiveCompletion(ftp.getClient().sendCommand("OPTS UTF8", "ON"))) {     ftp.getClient().setControlEncoding("UTF-8"); } else {    //FTP协议里面,规定文件名编码为iso-8859-1     ftp.getClient().setControlEncoding("ISO-8859-1"); } 

定时上传文件至ftp样例

引用工具组件:hutool

package cn.dexter.filesync;  import cn.dexter.filesync.metadata.sync.util.PropertiesUtils; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.ftp.Ftp; import org.apache.commons.net.ftp.FTPReply;  import java.io.File; import java.time.Duration; import java.time.LocalDateTime; import java.util.List;  /**  * ftp文件上传服务  * 定时扫描文件路径上传至ftp服务器  *  * @author Dexter  */ public class FtpUploadThread extends Thread {      String url = PropertiesUtils.getString("ftp.url");     String username = PropertiesUtils.getString("ftp.username");     String password = PropertiesUtils.getString("ftp.password");     /**      * 本地扫描路径      */     String messageLocalPath = PropertiesUtils.getString("file.localPath");     /**      * 本地服务端主题,用于区分文件来源      */     String svrTopic = PropertiesUtils.getString("svrTopic");      @Override     public void run() {         try {             List fileList = FileUtil.loopFiles(messageLocalPath);             if (fileList.size() > 0) {                 LocalDateTime starttime = LocalDateTime.now();                 Ftp ftp = new Ftp(url, 21, username, password);                 //开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就用本地编码(ISO-8859-1)                 if (FTPReply.isPositiveCompletion(ftp.getClient().sendCommand("OPTS UTF8", "ON"))) {                     ftp.getClient().setControlEncoding("UTF-8");                 } else {                    //FTP协议里面,规定文件名编码为iso-8859-1                     ftp.getClient().setControlEncoding("ISO-8859-1");                 }                 //设置被动模式                 ftp.getClient().enterLocalActiveMode();                   for (File file : fileList) {                     if (file.isFile()) {                         //每次上传后切换操作路径为根路径                         ftp.cd("/");                         //读取文件绝对路径                         String absolutePath = file.getAbsolutePath().replace("\\", "/");                         String fileName = file.getName();                         //替换ftp服务器远程根路径                         String remotePath = absolutePath.replace(messageLocalPath, "").replace(fileName, "");                         if (StrUtil.isNotBlank(svrTopic)) {                             //添加服务器主题                             remotePath = svrTopic + "/" + remotePath;                         }                         try {                             if (ftp.upload(remotePath, fileName, file)) {                                 //文件上传成功后,删除本地数据。                                 FileUtil.del(file);                             }                         } catch (IORuntimeException e) {                             System.out.println(String.format("上传文件[%s]失败!", absolutePath));                         }                     }                  }                 ftp.close();                 LocalDateTime endttime = LocalDateTime.now();                 Duration duration = Duration.between(starttime, endttime);                 System.out.println(String.format(" 本次文件同步耗时:%s分钟 %s秒", duration.toMinutes(), duration.toMillis() / 1000));             }         } catch (Exception e) {             System.out.println(String.format("上传文件至ftp服务器异常:%s", e.getMessage()));         }     } }  

相关内容

热门资讯

绝活儿辅助!广西老友玩老是输怎... 绝活儿辅助!广西老友玩老是输怎么办(辅助挂)都是真的有辅助app(讲解有挂)在进入广西老友玩老是输怎...
法门辅助!福建13水插件(辅助... 法门辅助!福建13水插件(辅助挂)一贯是有辅助技巧(有挂技术)1、许多玩家不知道福建13水插件辅助怎...
办法辅助!潮友会app下载官方... 办法辅助!潮友会app下载官方辅助器(辅助挂)真是真的是有辅助app(有挂教程)该软件可以轻松地帮助...
妙招辅助!邯郸胡乐挂辅助(辅助... 妙招辅助!邯郸胡乐挂辅助(辅助挂)好像存在有辅助插件(有挂方略)1、上手简单,内置详细流程视频教学,...
教程书辅助!乐酷辅助(辅助挂)... 教程书辅助!乐酷辅助(辅助挂)其实存在有辅助脚本(有挂细节)乐酷辅助能透视中分为三种模型:乐酷辅助模...
学习辅助!决战卡五星辅助(辅助... 学习辅助!决战卡五星辅助(辅助挂)本来真的是有辅助软件(有人有挂)学习辅助!决战卡五星辅助(辅助挂)...
绝活辅助!边锋嘉兴麻将辅助器(... 绝活辅助!边锋嘉兴麻将辅助器(辅助挂)真是真的有辅助神器(新版有挂)1、边锋嘉兴麻将辅助器公共底牌简...
举措辅助!枫叶辅助器(辅助挂)... 举措辅助!枫叶辅助器(辅助挂)本来存在有辅助技巧(竟然有挂)1、下载好枫叶辅助器正确养号方法之后点击...
讲义辅助!点我达辅助(辅助挂)... 讲义辅助!点我达辅助(辅助挂)一直存在有辅助技巧(有人有挂)1、点我达辅助辅助器安装包、点我达辅助辅...
模块辅助!威信茶馆有挂的吗(辅... 模块辅助!威信茶馆有挂的吗(辅助挂)一直真的是有辅助脚本(揭秘有挂)1、玩家可以在威信茶馆有挂的吗线...