java中删除FTP文件失败问题(ftpclient.deletefile)

之前删除FTP指定文件夹下文件一直失败,找了半天发现是文件名的问题。
使用ftpclient.deletefile(fileName)删除一直有问题

开始猜测是权限原因,于是用ftp工具尝试删除,发现可以删除。

那就有问题了。
原因:
FTP协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名包含中文需要转码。

解决方案:
将中文的目录或文件名转为iso-8859-1编码的字符。参考代码:

  boolean dele = ftp.deleteFile(new String(fileName.getBytes("utf-8"),"iso-8859-1"));

然后就能删除成功了。

FTP工具类:

package com.cetc.file.admin.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;


import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class FtpUtil {


    public static List<String> list = new ArrayList<>();

    public static Integer getFTPClient(String ftpHost, Integer ftpPort, String ftpUserName, String ftpPassword){
        //1:成功链接  0:链接失败
        Integer status ;
        FTPClient ftpClient = null;
        try {
            ftpClient = new FTPClient();
            ftpClient.setConnectTimeout(60000);
            if(ftpPort != null){
                ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            }else {
                ftpClient.connect(ftpHost);// 连接FTP服务器
            }
            if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                if (ftpClient.login(ftpUserName, ftpPassword)) {// 登陆FTP服务器
                    if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
                            "OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
                        ftpClient.setControlEncoding("UTF-8");
                    }else {
                        ftpClient.setControlEncoding("GBK");
                    }
                    ftpClient.enterLocalPassiveMode();// 设置被动模式
                    ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式,以二进制流的方式读取
                    ftpClient.enterLocalPassiveMode();
                    System.out.println("FTP服务连接成功!");
                    status = 1;
                }else {
                    System.out.println("FTP服务用户名或密码错误!");
                    status = 0;
                    disConnection(ftpClient);
                }
            }else {
                System.out.println("连接到FTP服务失败!");
                status = 0;
                disConnection(ftpClient);
            }
        } catch (SocketException e) {
            e.printStackTrace();
            status = 0;
            disConnection(ftpClient);
            System.out.println("FTP的IP地址可能错误,请正确配置。");
        } catch (IOException e) {
            e.printStackTrace();
            status = 0;
            disConnection(ftpClient);
            System.out.println("FTP的端口错误,请正确配置。");
        }finally {
            disConnection(ftpClient);
        }
        return status;
    }

    /**
     * 关闭FTP服务链接
     * @throws IOException
     */
    public static void disConnection(FTPClient ftpClient){
        try {
            if(ftpClient.isConnected()){
                ftpClient.disconnect();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 链接ftp
     * @param ftpHost
     * @param ftpUserName
     * @param ftpPassword
     * @param ftpPort
     * @return
     */
    public static FTPClient getFTPClients(String ftpHost, String ftpUserName,
                                         String ftpPassword, int ftpPort) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            ftpClient.setBufferSize(1024);
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand(
                    "OPTS UTF8", "ON"))) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
                ftpClient.setControlEncoding("UTF-8");
            }else {
                ftpClient.setControlEncoding("GBK");
            }
            ftpClient.enterLocalPassiveMode();// 设置被动模式
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式,以二进制流的方式读取
            ftpClient.enterLocalPassiveMode();
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();
                log.error("未连接到FTP,用户名或密码错误。");
            } else {
                log.info("FTP connection success");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            log.error("FTP的IP地址可能错误,请正确配置。");
        } catch (IOException e) {
            log.error("FTP的IP地址可能错误,请正确配置。");
        }
        return ftpClient;
    }


    /**
     * 从FTP服务器上下载文件
     *
     * @param name   ftp服务器文件路径,以/dir形式开始
     * @param localDirectoryAndFileName 保存到本地的目录
     * @return
     */
    public static List<String> get(FTPClient ftpClient, String name, String localDirectoryAndFileName) {
        ftpClient.enterLocalPassiveMode(); // Use passive mode as default
        try {
            list.clear();
            List<String> files = List(ftpClient, name);
            for(String ftpDirectoryAndFileName : files){
                // 将路径中的斜杠统一
                char[] chars = ftpDirectoryAndFileName.toCharArray();
                StringBuffer sbStr = new StringBuffer(256);
                for (int i = 0; i < chars.length; i++) {
                    if ('\\' == chars[i]) {
                        sbStr.append('/');
                    } else {
                        sbStr.append(chars[i]);
                    }
                }
                ftpDirectoryAndFileName =sbStr.toString();
                String filePath = ftpDirectoryAndFileName.substring(0, ftpDirectoryAndFileName.lastIndexOf("/"));
                String fileName = ftpDirectoryAndFileName.substring(ftpDirectoryAndFileName.lastIndexOf("/") + 1);
                changeDir(ftpClient,filePath);
                ftpClient.retrieveFile(new String(fileName.getBytes(), "iso-8859-1"),
                        new FileOutputStream(localDirectoryAndFileName+fileName)); // download
                /*ftpClient.changeWorkingDirectory("/");*/
                System.out.println(ftpClient.printWorkingDirectory());
                if(ftpClient!=null){
                    boolean b = ftpClient.deleteFile(new String(fileName.getBytes("utf-8"),"iso-8859-1"));
                    System.out.println("删除文件"+b);
                }else {
                    log.error("FTP链接关闭");
                }
                // file
                System.out.println(ftpClient.getReplyString()); // check result
                System.out.println("从ftp服务器上下载文件:" + ftpDirectoryAndFileName + ", 保存到:" + localDirectoryAndFileName);
            }
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 层层切换工作目录
     *
     * @param ftpPath 目的目录
     * @return 切换结果
     */
    public static boolean changeDir(FTPClient ftpClient,String ftpPath) {
        if (!ftpClient.isConnected()) {
            return false;
        }
        try {
            // 将路径中的斜杠统一
            char[] chars = ftpPath.toCharArray();
            StringBuffer sbStr = new StringBuffer(256);
            for (int i = 0; i < chars.length; i++) {
                if ('\\' == chars[i]) {
                    sbStr.append('/');
                } else {
                    sbStr.append(chars[i]);
                }
            }
            ftpPath = sbStr.toString();
            if (ftpPath.indexOf('/') == -1) {
                // 只有一层目录
                ftpClient.changeWorkingDirectory(new String(ftpPath.getBytes(), "iso-8859-1"));
            } else {
                // 多层目录循环创建
                String[] paths = ftpPath.split("/");
                for (int i = 0; i < paths.length; i++) {
                    ftpClient.changeWorkingDirectory(new String(paths[i].getBytes(), "iso-8859-1"));
                }
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 递归获取文件夹下文件
     * @param ftpClient
     * @param pathName
     * @return
     * @throws IOException
     */
    public static List<String> List(FTPClient ftpClient, String pathName) throws IOException{
        if (pathName.startsWith("/") && !pathName.contains(".")) {//更换目录到当前目录
            ftpClient.changeWorkingDirectory(pathName);
            FTPFile[] files= ftpClient.listFiles();
            for(FTPFile file : files) {
                if(file.isFile()) {
                    list.add(pathName+File.separator+file.getName());
                }else if(file.isDirectory()) {//需要加此判断。否则,ftp默认将‘项目文件所在目录之下的目录(./)’与‘项目文件所在目录向上一级目录下的目录(../)’都纳入递归,这样下去就陷入一个死循环了。需将其过滤掉。
                    if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
                         List(ftpClient,"/"+pathName+"/"+file.getName());
                }
            }
            }
        }else{
            list.add(pathName);
        }
        return list;
    }

}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值