linux中ftp中文名乱码问题
问题触发环境
1. java中使用org.apache.commons.net.ftp.FTPClient包
2. 通过chrome浏览器的file标签上传文件
3. 在windows上部署的FileZilla服务上传的文件名正常显示,在linux上的vsftpd服务文件名显示乱码
4. 直接chrome浏览器访问linux的ftp目录(chrome的默认编码是UTF-8),正常显示
5. 乱码出现后,尝试了各种方式编码处理,造成了环境的各种不可追溯
解决过程
1. 查询资料:FTP协议规定文件名编码为iso-8859-1,所以上传的文件目录或文件名需要转码
2. 参考FileZilla的流程,会向FTP服务器发送OPTS UTF8 ON命令,开启服务器对UTF-8的支持。
3. 仿照FileZilla的方式,可向服务器发送该指令,如果服务器支持UTF-8则使用UTF-8,否则使用本地编码(GBK)处理中文名
4. 起作用的java关键代码
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异常
web项目开发中出现乱码,要从传值开始分析编码,逐步排查,确保编码一致。要注意浏览器和某些方法的默认行为(场景较多,需要时查询即可,不在此处罗列)
测试后的代码托管在GitHub中,地址https://github.com/Hlingoes/file-message-server,位于application/FtpService中,供参考和提出改进建议
linux中ftp中文名乱码问题的更多相关文章
- Windows转到linux中,文件乱码,文件编码转换 & 解决sqlplus连接oracle乱码
转载:http://www.cnblogs.com/wanyao/p/3399269.html 最近,学习又重新开始Linux学习,所以一直在Centos中,昨天一朋友把他在Windows下写的C程序 ...
- Linux中ftp不能上传文件/目录的解决办法
在linux中不能上传文件或文件夹最多的问题就是权限问题,但有时也不一定是权限问题了,像我就是空间不够用了,下面我来总结一些ftp不能上传文件/目录的解决办法 在排除用户组和权限等问题后,最可能引 ...
- Windows转到linux中,文件乱码,文件编码转换
最近,学习又重新开始Linux学习,所以一直在Centos中,昨天一朋友把他在Windows下写的C程序发给我,我欣然答应,本以为很快就能在我的Linux系统中运行起来.没想到出现了乱码,结果想把这个 ...
- linux中FTP自动备份VPS脚本
服务器多了,网站也越来越多,总觉得不整个备份心里放不下心,并且有好几次rm的操作失误,造成难以挽回的损失.并且大多数的VPS提供商是不提供自动备份功能或者此功能收费价格略高.所以自己还是有必要把这个工 ...
- Linux 中 Windows 中文乱码
Linux 下 Windows 源代码中文乱码 由于 windows 和 linux 对文本的编码方式不同,所以经常会有 windows 中生成的文本在 linux 中打开乱码的情况. 比如: 我面临 ...
- Linux中重命名乱码文件
Linux下,如何将一个乱码的文件进行重命名 方法一: 命令格式:mv $(ls |egrep "[^a-zA-Z0-9.-]") tandao.tx [root@nb o]# l ...
- Linux中ftp服务器搭建
一.FTP工作原理 (1)FTP使用端口 [root@localhost ~]# cat /etc/services | grep ftp ftp-data 20/tcp #数据链路:端口20 ftp ...
- Linux中ftp的常用命令
转自:https://www.jb51.net/article/103904.htm FTP命令 ftp> ascii # 设定以ASCII方式传送文件(缺省值) ftp> bell # ...
- Linux中FTP远程传输,SSH远程连接,以及SCP远程拷贝
常用服务器ftp.ssh 1. Linux常用服务器构建-ftp服务器 ftp服务器 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”. 用于 ...
随机推荐
- 安装与配置windbg的symbol(符号)
http://msdn.microsoft.com/en-us/windows/hardware/gg463028.aspx windows symbols下载地址 本篇是新手自己写的一点心得.建议 ...
- 从GitLab上拉到本地仓库的项目导入到eclipse中
拉项目 在本地仓库中右键git clone,填写地址 OK, 然后在拉下来的项目上面右键检出创建dev分支. 要将新分支导入到eclipse中, 如果是没有导入过就选第三个,导入过就选第一个. 然后O ...
- python字符串常用函数
# 索引与切片 *** capitalize() **首字母大写 upper() lower() *** 大写和小写函数 startswith endswith *** 判断以‘’字母’开 ...
- Ganglia 安装 No package 'ck' found
安装ConcurrecyKit,下载地址:https://github.com/concurrencykit/ck 编译安装即可 下面是一个歪果仁的解决办法,不过我没用上 I was buildi ...
- 路由反射器(RR)配置
IBGP与EBGP的区别:是否使用指定源(update-source) 路由反射器(RR)配置: 零:关闭同步,关闭自动汇总. ①:启用BGP ②:在相同BGP-AS下建立邻居. ③:指定路由器及所在 ...
- 【STM32H7教程】第48章 STM32H7的FMC总线应用之是32路高速IO扩展
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第48章 STM32H7的FMC总线应用之是32路 ...
- JS下拉框联动
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- swift中实现cell中局部播放的动画效果
在cell中 // 播放器动画效果 private var replicatorLayer:ReplicatorLayer = { let layer = ReplicatorLayer.init(f ...
- Aspectj切入点语法定义
例如定义切入点表达式 execution (* com.sample.service.impl..*.*(..)) execution()是最常用的切点函数,其语法如下所示: 整个表达式可以分为五个 ...
- C语言的字符串类型
C语言使用指针来管理字符串(1)C语言中定义字符串的方法:char *p = "linux";此时p就叫字符串,但是实际上p只是一个字符指针(本质上就是一个指针变量,只是p指向了一 ...