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

文章讲述了在Java中遇到FTP上传中文文件名出现乱码的问题,尝试了文件名的编码转换和修改IISFTP服务器设置无效。最终通过发送OPTSUTF8ON命令来开启FTP服务器的UTF-8支持,并使用Hutool库实现定时上传文件到FTP服务器,成功解决了中文文件名乱码的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

说明

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

无效踩坑经历


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");
    }
    

请添加图片描述

有效解决方法

思路:设置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<File> 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()));
        }
    }
}

### 回答1: 在Ubuntu下开启FTP服务可能会出现乱码问题,主要是因为FTP服务默认使用的字符编码与我们在终端或文本编辑器中使用的字符编码可能不一致。为了解决这个问题,可以按照以下步骤进行操作: 1. 打开终端,使用root用户或拥有sudo权限的用户登录。 2. 编辑FTP服务器的配置文件 vsftpd.conf,可以使用以下命令进行编辑: sudo nano /etc/vsftpd.conf 3. 在配置文件中找到以下两行内容,并确保其被注释掉(即行首加上#号): #utf8_filesystem=YES #utf8_upload=YES 4. 在配置文件的最后添加以下两行内容: charset=utf-8 force_local_logins_ssl=YES 5. 保存修改(按下Ctrl + X,然后按下Y键,最后按下Enter键)并退出编辑器。 6. 重启FTP服务,可以使用以下命令进行重启: sudo systemctl restart vsftpd 7. 现在重新连接FTP服务器,应该能够正确显示文件名及内容的中文字符了。 通过以上操作,可以解决在Ubuntu下开启FTP服务时可能出现的乱码问题。需要注意的是,以上步骤可能会因不同的环境而略有差异,建议根据实际情况进行调整。 ### 回答2: 在Ubuntu下开启FTP服务时,如果出现乱码问题,可以尝试以下解决方法: 1. 编辑vsftpd配置文件:打开终端,输入命令 sudo vim /etc/vsftpd.conf 打开vsftpd的配置文件。 2. 设置字符编码:在配置文件中找到"utf8_filesystem=YES",确保该行没有被注释掉。若被注释掉,则将其取消注释。 3. 重新启动vsftpd服务:在终端中输入命令 sudo service vsftpd restart,以重新启动vsftpd服务。 4. 配置FTP客户端:对于连接FTP服务器的客户端,如FileZilla等,需要设置字符编码为UTF-8或者自动检测编码,以保证文件传输时不会出现乱码。 另外,如果FTP服务器上的文件名出现乱码,可以使用以下方法解决: 1. 修改文件名字符编码:在Ubuntu终端中,使用命令 sudo apt-get install convmv 安装convmv工具。然后使用命令 convmv -f 源字符编码 -t 目标字符编码 --notest 目标文件名,将文件名从源编码转换为目标编码。 2. 修改默认字符编码:在Ubuntu终端中,打开 /etc/default/locale 文件,将其中的LANG值设置为与FTP服务器上的文件名使用的字符编码相匹配的编码,如en_US.UTF-8等。然后保存文件并重启系统,使得字符编码修改生效。 以上是处理Ubuntu下FTP乱码问题的一些方法。希望能对你有所帮助! ### 回答3: 在Ubuntu下,如果遇到FTP乱码问题,您可以尝试以下几种解决方法。 1. 检查FTP客户端设置:在使用FTP客户端连接服务器之前,先检查FTP客户端的字符编码设置是否正确。确保设置为UTF-8编码,以避免乱码问题。可以通过查看FTP客户端的设置选项或者帮助文档找到相关设置。 2. 检查服务器端设置:登录到FTP服务器,查看服务器的字符编码设置。通常,Ubuntu使用UTF-8编码作为默认编码。如果服务器的字符编码设置不正确,可以尝试修改为UTF-8编码。 3. 修改FTP服务器配置文件:找到FTP服务器的配置文件,通常位于/etc/vsftpd.conf或/etc/proftpd.conf。打开配置文件,查找并修改以下配置项: - 如果使用vsftpd服务器,找到 local_charset 项,将其更改为UTF-8。 - 如果使用proftpd服务器,找到 DefaultRoot配置段,并添加以下内容: DefaultRoot ~ SetEnv LANG en_US.UTF-8 4. 重新启动FTP服务器:修改FTP服务器配置文件后,保存并退出。然后,重新启动FTP服务器,以使更改生效。可以使用以下命令重启FTP服务器: - 对于vsftpd服务器:sudo systemctl restart vsftpd - 对于proftpd服务器:sudo systemctl restart proftpd 5. 检查文件的字符编码:如果在上传或下载文件时出现乱码问题,可以检查文件的字符编码。可以使用“file”命令来检查文件的编码类型,例如:file filename。确保文件的编码类型与系统和FTP客户端的设置相匹配。 总结起来,解决Ubuntu下FTP乱码问题的关键是确保FTP客户端和服务器的字符编码设置正确,并在需要的情况下修改服务器配置文件。同时,还应该检查文件的字符编码,以确保与系统和FTP客户端的设置一致。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值